[解決済み】Javaでファイル内の行数について
2022-04-06 02:21:30
質問
私は巨大なデータファイルを使用していますが、時々、これらのファイルの行数を知る必要があります。通常は、ファイルを開いて、ファイルの終わりに達するまで行ごとに読みます。
もっとスマートな方法はないものかと考えていました。
どのように解決するのですか?
これは私がこれまで見つけた中で最速のバージョンで、readLinesの約6倍の速さです。150MBのログファイルでは、readLines()を使った場合の2.40秒に対して、0.35秒で済みます。ちなみに、linuxのwc -lコマンドは0.15秒です。
public static int countLinesOld(String filename) throws IOException {
InputStream is = new BufferedInputStream(new FileInputStream(filename));
try {
byte[] c = new byte[1024];
int count = 0;
int readChars = 0;
boolean empty = true;
while ((readChars = is.read(c)) != -1) {
empty = false;
for (int i = 0; i < readChars; ++i) {
if (c[i] == '\n') {
++count;
}
}
}
return (count == 0 && !empty) ? 1 : count;
} finally {
is.close();
}
}
EDIT、9年半後。私は実質的にJavaの経験がないのですが、とにかくこのコードのベンチマークを
LineNumberReader
というのも、誰もやっていないことが気になったからです。特に大きなファイルに対しては、私のソリューションの方が速いようです。しかし、オプティマイザがまともな仕事をするまで、何回か実行する必要があるようです。私はコードを少し弄って、常に最速となる新しいバージョンを作りました。
public static int countLinesNew(String filename) throws IOException {
InputStream is = new BufferedInputStream(new FileInputStream(filename));
try {
byte[] c = new byte[1024];
int readChars = is.read(c);
if (readChars == -1) {
// bail out if nothing to read
return 0;
}
// make it easy for the optimizer to tune this loop
int count = 0;
while (readChars == 1024) {
for (int i=0; i<1024;) {
if (c[i++] == '\n') {
++count;
}
}
readChars = is.read(c);
}
// count remaining characters
while (readChars != -1) {
System.out.println(readChars);
for (int i=0; i<readChars; ++i) {
if (c[i] == '\n') {
++count;
}
}
readChars = is.read(c);
}
return count == 0 ? 1 : count;
} finally {
is.close();
}
}
1.3GB のテキストファイルのベンチマーク結果、Y 軸は秒。同じファイルを使って100回実行し、それぞれの実行を
System.nanoTime()
. ご覧の通り
countLinesOld
にはいくつかの異常値があり
countLinesNew
がなく、ほんの少し速いだけですが、その差は統計的に有意です。
LineNumberReader
は明らかに遅い。
関連
-
[解決済み] javascriptでExpression言語を使うには?
-
[解決済み] JDBC タイプの方言マッピングがありません。1111
-
[解決済み] JavaでInputStreamを読み込んでStringに変換するにはどうすればよいですか?
-
[解決済み] JavaでNullPointerExceptionを回避する方法
-
[解決済み] JavaにおけるHashMapとHashtableの違いは何ですか?
-
[解決済み] Java Mapの各エントリを効率的に反復処理するには?
-
[解決済み] Javaでメモリーリークを発生させるにはどうしたらいいですか?
-
[解決済み] JavaでArrayListではなくLinkedListを使用するのはいつですか?
-
[解決済み] JavaでStringをintに変換するにはどうしたらいいですか?
-
[解決済み] 整数の平方根が整数であるかどうかを判断する最速の方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Application startメソッドで例外が発生する。JavaFx 11
-
[解決済み] enumのordinalを使用するのは良い習慣ですか?
-
[解決済み] java.lang.IncompatibleClassChangeError: Mongo クラスを実装しています。
-
[解決済み] double 型を Int 型に変換、切り捨て
-
[解決済み] Androidのコールバックとは何ですか?重複
-
[解決済み] JOGLまたはLWJGLの既成のプロジェクト
-
[解決済み] java.lang.ClassNotFoundException: クラス com.ibm.db2.jcc.DB2Driver が Worklight プラットフォームまたはプロジェクトに見つかりませんでした。
-
[解決済み] java.util.MissingFormatArgumentException: 形式指定子 '%s' がありません。
-
[解決済み] Java の文字列インデックスが範囲外です。0 [閉店]
-
[解決済み] なぜテキストファイルは改行で終わらなければならないのですか?