多数の小さなファイルをメモリに読み込む最速の方法は何ですか?
-
05-07-2019 - |
質問
サーバーの起動ごとに最大50ファイルを読み取り、各テキストファイルの表現をメモリに配置する必要があります。各テキストファイルには独自の文字列があります(文字列ホルダーに使用するのに最適なタイプは?)。
ファイルをメモリに読み込む最速の方法は何ですか?また、メモリ内でテキストを操作できるようにテキストを保持するのに最適なデータ構造/タイプは何ですか?(主に検索と置換)
ありがとう
解決
メモリマッピングされたファイルは最速になります...次のようになります:
final File file;
final FileChannel channel;
final MappedByteBuffer buffer;
file = new File(fileName);
fin = new FileInputStream(file);
channel = fin.getChannel();
buffer = channel.map(MapMode.READ_ONLY, 0, file.length());
次に、バイトバッファからの読み取りに進みます。
これは、 FileInputStream
または FileReader
よりも大幅に高速になります。
編集:
これについて少し調査した結果、お使いのOSによっては、代わりに新しい BufferedInputStream(new FileInputStream(file))
を使用した方が良い場合があることがわかりました。ただし、すべてを一度にchar []に読み込むと、ファイルのサイズが最悪のように聞こえます。
したがって、 BufferedInputStream
は、すべてのプラットフォームでほぼ一貫したパフォーマンスを提供する必要がありますが、メモリマップファイルは、基盤となるOSによって低速または高速になる場合があります。パフォーマンスが重要なすべてのものと同様に、コードをテストし、何が最適かを確認する必要があります。
編集:
OKここにいくつかのテストがあります(最初のテストはファイルをディスクキャッシュに入れるために2回行われます)。
私はrt.jarクラスファイルで実行し、ハードドライブに抽出しました。これはWindows 7ベータx64の下です。それは、合計94,706,637バイトの16784ファイルです。
最初の結果...
(ディスクキャッシュの設定を取得するために最初の手順が繰り返されることを思い出してください)
-
ArrayTest
- 時間= 83016
- バイト= 118641472
-
ArrayTest
- 時間= 46570
- バイト= 118641472
-
DataInputByteAtATime
- 時間= 74735
- バイト= 118641472
-
DataInputReadFully
- 時間= 8953
- バイト= 118641472
-
MemoryMapped
- 時間= 2320
- バイト= 118641472
ここにコードがあります...
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.util.HashSet;
import java.util.Set;
public class Main
{
public static void main(final String[] argv)
{
ArrayTest.main(argv);
ArrayTest.main(argv);
DataInputByteAtATime.main(argv);
DataInputReadFully.main(argv);
MemoryMapped.main(argv);
}
}
abstract class Test
{
public final void run(final File root)
{
final Set<File> files;
final long size;
final long start;
final long end;
final long total;
files = new HashSet<File>();
getFiles(root, files);
start = System.currentTimeMillis();
size = readFiles(files);
end = System.currentTimeMillis();
total = end - start;
System.out.println(getClass().getName());
System.out.println("time = " + total);
System.out.println("bytes = " + size);
}
private void getFiles(final File dir,
final Set<File> files)
{
final File[] childeren;
childeren = dir.listFiles();
for(final File child : childeren)
{
if(child.isFile())
{
files.add(child);
}
else
{
getFiles(child, files);
}
}
}
private long readFiles(final Set<File> files)
{
long size;
size = 0;
for(final File file : files)
{
size += readFile(file);
}
return (size);
}
protected abstract long readFile(File file);
}
class ArrayTest
extends Test
{
public static void main(final String[] argv)
{
final Test test;
test = new ArrayTest();
test.run(new File(argv[0]));
}
protected long readFile(final File file)
{
InputStream stream;
stream = null;
try
{
final byte[] data;
int soFar;
int sum;
stream = new BufferedInputStream(new FileInputStream(file));
data = new byte[(int)file.length()];
soFar = 0;
do
{
soFar += stream.read(data, soFar, data.length - soFar);
}
while(soFar != data.length);
sum = 0;
for(final byte b : data)
{
sum += b;
}
return (sum);
}
catch(final IOException ex)
{
ex.printStackTrace();
}
finally
{
if(stream != null)
{
try
{
stream.close();
}
catch(final IOException ex)
{
ex.printStackTrace();
}
}
}
return (0);
}
}
class DataInputByteAtATime
extends Test
{
public static void main(final String[] argv)
{
final Test test;
test = new DataInputByteAtATime();
test.run(new File(argv[0]));
}
protected long readFile(final File file)
{
DataInputStream stream;
stream = null;
try
{
final int fileSize;
int sum;
stream = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
fileSize = (int)file.length();
sum = 0;
for(int i = 0; i < fileSize; i++)
{
sum += stream.readByte();
}
return (sum);
}
catch(final IOException ex)
{
ex.printStackTrace();
}
finally
{
if(stream != null)
{
try
{
stream.close();
}
catch(final IOException ex)
{
ex.printStackTrace();
}
}
}
return (0);
}
}
class DataInputReadFully
extends Test
{
public static void main(final String[] argv)
{
final Test test;
test = new DataInputReadFully();
test.run(new File(argv[0]));
}
protected long readFile(final File file)
{
DataInputStream stream;
stream = null;
try
{
final byte[] data;
int sum;
stream = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
data = new byte[(int)file.length()];
stream.readFully(data);
sum = 0;
for(final byte b : data)
{
sum += b;
}
return (sum);
}
catch(final IOException ex)
{
ex.printStackTrace();
}
finally
{
if(stream != null)
{
try
{
stream.close();
}
catch(final IOException ex)
{
ex.printStackTrace();
}
}
}
return (0);
}
}
class DataInputReadInChunks
extends Test
{
public static void main(final String[] argv)
{
final Test test;
test = new DataInputReadInChunks();
test.run(new File(argv[0]));
}
protected long readFile(final File file)
{
DataInputStream stream;
stream = null;
try
{
final byte[] data;
int size;
final int fileSize;
int sum;
stream = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
fileSize = (int)file.length();
data = new byte[512];
size = 0;
sum = 0;
do
{
size += stream.read(data);
sum = 0;
for(int i = 0; i < size; i++)
{
sum += data[i];
}
}
while(size != fileSize);
return (sum);
}
catch(final IOException ex)
{
ex.printStackTrace();
}
finally
{
if(stream != null)
{
try
{
stream.close();
}
catch(final IOException ex)
{
ex.printStackTrace();
}
}
}
return (0);
}
}
class MemoryMapped
extends Test
{
public static void main(final String[] argv)
{
final Test test;
test = new MemoryMapped();
test.run(new File(argv[0]));
}
protected long readFile(final File file)
{
FileInputStream stream;
stream = null;
try
{
final FileChannel channel;
final MappedByteBuffer buffer;
final int fileSize;
int sum;
stream = new FileInputStream(file);
channel = stream.getChannel();
buffer = channel.map(MapMode.READ_ONLY, 0, file.length());
fileSize = (int)file.length();
sum = 0;
for(int i = 0; i < fileSize; i++)
{
sum += buffer.get();
}
return (sum);
}
catch(final IOException ex)
{
ex.printStackTrace();
}
finally
{
if(stream != null)
{
try
{
stream.close();
}
catch(final IOException ex)
{
ex.printStackTrace();
}
}
}
return (0);
}
}
他のヒント
最も効率的な方法は次のとおりです。
- ファイルの長さを決定する(
File.length()
) - 同じサイズ(またはわずかに大きい)の文字バッファーを作成します
- ファイルのエンコードを決定します
-
new InputStreamReader(new FileInputStream(file)、encoding)
を使用して読み取り - read()を1回呼び出して、whileファイルをバッファに読み込みます。 read()は早期に戻る場合があることに注意してください(ファイル全体を読み取ったわけではありません)。その場合、次のバッチを読み取るために、オフセットを付けて再度呼び出します。
- 文字列を作成します:
new String(buffer)
起動時に一度検索と置換が必要な場合は、String.replaceAll()を使用します。
繰り返し行う必要がある場合は、StringBuilderの使用を検討してください。 replaceAll()はありませんが、これを使用して文字配列を適切に操作できます(-&gt;メモリの割り当てなし)。
それは言った:
- コードをできるだけ短くシンプルにします。
- パフォーマンスを測定する
- 遅すぎるので修正してください。
実行に0.1秒しかかからない場合、このコードを高速に実行するために多くの時間を無駄にする理由はありません。
まだパフォーマンスの問題がある場合は、すべてのテキストファイルをJARに入れてクラスパスに追加し、Class.getResourceAsStream()を使用してファイルを読み取ることを検討してください。 Javaクラスパスからの読み込みは高度に最適化されています。
それは、テキストファイルの内部構造とそれらを使用して何をするかによって大きく異なります。
ファイルはKey-Value辞書(つまり、「プロパティ」ファイル)ですか? XML? JSON?それらの標準構造があります。
形式的な構造を持っている場合は、JavaCCを使用してファイルのオブジェクト表現を構築することもできます。
それ以外の場合、それらが単なるデータの塊である場合は、ファイルを読み取り、文字列に入れます。
編集:検索と置換について-juste use StringのreplaceAll関数。
GoogleでJavaのIO速度に関する既存のテストを検索した後、TofuBearのテストケースが完全に目を開いたと言わざるを得ません。自分のプラットフォームで彼のテストを実行して、あなたにとって最速のものを確認する必要があります。
彼のテストを実行し、自分のコードをいくつか追加した後(元のコードを投稿したことをTofuBearにクレジット)、独自のカスタムバッファーを使用するか、BufferedInputStreamを使用することで、さらに高速になる可能性があります。
残念なことに、NIO ByteBufferはうまく機能しませんでした。
注:静的byte []バッファーは数ミリ秒削り取られましたが、静的ByteBuffersは実際に処理時間を増やしました! コードに何か問題がありますか?
いくつかのテストを追加しました:
-
ArrayTest_CustomBuffering(データを自分のバッファーに直接読み込む)
-
ArrayTest_CustomBuffering_StaticBuffer(最初に一度だけ作成される静的バッファーにデータを読み取ります)
-
FileChannelArrayByteBuffer(NIO ByteBufferを使用して独自のbyte []配列をラップ)
-
FileChannelAllocateByteBuffer(.allocateでNIO ByteBufferを使用)
-
FileChannelAllocateByteBuffer_StaticBuffer(4と同じですが、静的バッファーを使用)
-
FileChannelAllocateDirectByteBuffer(NIO ByteBufferと.allocateDirectを使用)
-
FileChannelAllocateDirectByteBuffer_StaticBuffer(6と同じですが、静的バッファーを使用)
ここに私の結果があります:抽出されたrt.jarでWindows Vistaとjdk1.6.0_13を使用:
ArrayTest
時間= 2075
バイト= 2120336424
ArrayTest
時間= 2044
バイト= 2120336424
ArrayTest_CustomBuffering
時間= 1903
バイト= 2120336424
ArrayTest_CustomBuffering_StaticBuffer
時間= 1872
バイト= 2120336424
DataInputByteAtATime
時間= 2668
バイト= 2120336424
DataInputReadFully
時間= 2028
バイト= 2120336424
MemoryMapped
時間= 2901
バイト= 2120336424
FileChannelArrayByteBuffer
時間= 2371
バイト= 2120336424
FileChannelAllocateByteBuffer
時間= 2356
バイト= 2120336424
FileChannelAllocateByteBuffer_StaticBuffer
時間= 2668
バイト= 2120336424
FileChannelAllocateDirectByteBuffer
時間= 2512
バイト= 2120336424
FileChannelAllocateDirectByteBuffer_StaticBuffer
時間= 2590
バイト= 2120336424
TofuBearのコードのハッキングされたバージョン:
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.MappedByteBuffer;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.util.HashSet;
import java.util.Set;
public class Main {
public static void main(final String[] argv) {
ArrayTest.mainx(argv);
ArrayTest.mainx(argv);
ArrayTest_CustomBuffering.mainx(argv);
ArrayTest_CustomBuffering_StaticBuffer.mainx(argv);
DataInputByteAtATime.mainx(argv);
DataInputReadFully.mainx(argv);
MemoryMapped.mainx(argv);
FileChannelArrayByteBuffer.mainx(argv);
FileChannelAllocateByteBuffer.mainx(argv);
FileChannelAllocateByteBuffer_StaticBuffer.mainx(argv);
FileChannelAllocateDirectByteBuffer.mainx(argv);
FileChannelAllocateDirectByteBuffer_StaticBuffer.mainx(argv);
}
}
abstract class Test {
static final int BUFF_SIZE = 20971520;
static final byte[] StaticData = new byte[BUFF_SIZE];
static final ByteBuffer StaticBuffer =ByteBuffer.allocate(BUFF_SIZE);
static final ByteBuffer StaticDirectBuffer = ByteBuffer.allocateDirect(BUFF_SIZE);
public final void run(final File root) {
final Set<File> files;
final long size;
final long start;
final long end;
final long total;
files = new HashSet<File>();
getFiles(root, files);
start = System.currentTimeMillis();
size = readFiles(files);
end = System.currentTimeMillis();
total = end - start;
System.out.println(getClass().getName());
System.out.println("time = " + total);
System.out.println("bytes = " + size);
}
private void getFiles(final File dir,final Set<File> files) {
final File[] childeren;
childeren = dir.listFiles();
for(final File child : childeren) {
if(child.isFile()) {
files.add(child);
}
else {
getFiles(child, files);
}
}
}
private long readFiles(final Set<File> files) {
long size;
size = 0;
for(final File file : files) {
size += readFile(file);
}
return (size);
}
protected abstract long readFile(File file);
}
class ArrayTest extends Test {
public static void mainx(final String[] argv) {
final Test test;
test = new ArrayTest();
test.run(new File(argv[0]));
}
protected long readFile(final File file) {
InputStream stream;
stream = null;
try {
final byte[] data;
int soFar;
int sum;
stream = new BufferedInputStream(new FileInputStream(file));
data = new byte[(int)file.length()];
soFar = 0;
do {
soFar += stream.read(data, soFar, data.length - soFar);
}
while(soFar != data.length);
sum = 0;
for(final byte b : data) {
sum += b;
}
return (sum);
}
catch(final IOException ex) {
ex.printStackTrace();
}
finally {
if(stream != null) {
try {
stream.close();
}
catch(final IOException ex) {
ex.printStackTrace();
}
}
}
return (0);
}
}
class ArrayTest_CustomBuffering extends Test {
public static void mainx(final String[] argv) {
final Test test;
test = new ArrayTest_CustomBuffering();
test.run(new File(argv[0]));
}
protected long readFile(final File file) {
InputStream stream;
stream = null;
try {
final byte[] data;
int soFar;
int sum;
stream = new FileInputStream(file);
data = new byte[(int)file.length()];
soFar = 0;
do {
soFar += stream.read(data, soFar, data.length - soFar);
}
while(soFar != data.length);
sum = 0;
for(final byte b : data) {
sum += b;
}
return (sum);
}
catch(final IOException ex) {
ex.printStackTrace();
}
finally {
if(stream != null) {
try {
stream.close();
}
catch(final IOException ex) {
ex.printStackTrace();
}
}
}
return (0);
}
}
class ArrayTest_CustomBuffering_StaticBuffer extends Test {
public static void mainx(final String[] argv) {
final Test test;
test = new ArrayTest_CustomBuffering_StaticBuffer();
test.run(new File(argv[0]));
}
protected long readFile(final File file) {
InputStream stream;
stream = null;
try {
int soFar;
int sum;
final int fileSize;
stream = new FileInputStream(file);
fileSize = (int)file.length();
soFar = 0;
do {
soFar += stream.read(StaticData, soFar, fileSize - soFar);
}
while(soFar != fileSize);
sum = 0;
for(int i=0;i<fileSize;i++) {
sum += StaticData[i];
}
return (sum);
}
catch(final IOException ex) {
ex.printStackTrace();
}
finally {
if(stream != null) {
try {
stream.close();
}
catch(final IOException ex) {
ex.printStackTrace();
}
}
}
return (0);
}
}
class DataInputByteAtATime extends Test {
public static void mainx(final String[] argv) {
final Test test;
test = new DataInputByteAtATime();
test.run(new File(argv[0]));
}
protected long readFile(final File file) {
DataInputStream stream;
stream = null;
try {
final int fileSize;
int sum;
stream = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
fileSize = (int)file.length();
sum = 0;
for(int i = 0; i < fileSize; i++) {
sum += stream.readByte();
}
return (sum);
}
catch(final IOException ex) {
ex.printStackTrace();
}
finally {
if(stream != null) {
try {
stream.close();
}
catch(final IOException ex) {
ex.printStackTrace();
}
}
}
return (0);
}
}
class DataInputReadFully extends Test {
public static void mainx(final String[] argv) {
final Test test;
test = new DataInputReadFully();
test.run(new File(argv[0]));
}
protected long readFile(final File file) {
DataInputStream stream;
stream = null;
try {
final byte[] data;
int sum;
stream = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
data = new byte[(int)file.length()];
stream.readFully(data);
sum = 0;
for(final byte b : data) {
sum += b;
}
return (sum);
}
catch(final IOException ex) {
ex.printStackTrace();
}
finally {
if(stream != null) {
try {
stream.close();
}
catch(final IOException ex) {
ex.printStackTrace();
}
}
}
return (0);
}
}
class DataInputReadInChunks extends Test {
public static void mainx(final String[] argv) {
final Test test;
test = new DataInputReadInChunks();
test.run(new File(argv[0]));
}
protected long readFile(final File file) {
DataInputStream stream;
stream = null;
try {
final byte[] data;
int size;
final int fileSize;
int sum;
stream = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
fileSize = (int)file.length();
data = new byte[512];
size = 0;
sum = 0;
do {
size += stream.read(data);
sum = 0;
for(int i = 0;
i < size;
i++) {
sum += data[i];
}
}
while(size != fileSize);
return (sum);
}
catch(final IOException ex) {
ex.printStackTrace();
}
finally {
if(stream != null) {
try {
stream.close();
}
catch(final IOException ex) {
ex.printStackTrace();
}
}
}
return (0);
}
}
class MemoryMapped extends Test {
public static void mainx(final String[] argv) {
final Test test;
test = new MemoryMapped();
test.run(new File(argv[0]));
}
protected long readFile(final File file) {
FileInputStream stream;
stream = null;
try {
final FileChannel channel;
final MappedByteBuffer buffer;
final int fileSize;
int sum;
stream = new FileInputStream(file);
channel = stream.getChannel();
buffer = channel.map(MapMode.READ_ONLY, 0, file.length());
fileSize = (int)file.length();
sum = 0;
for(int i = 0; i < fileSize; i++) {
sum += buffer.get();
}
return (sum);
}
catch(final IOException ex) {
ex.printStackTrace();
}
finally {
if(stream != null) {
try {
stream.close();
}
catch(final IOException ex) {
ex.printStackTrace();
}
}
}
return (0);
}
}
class FileChannelArrayByteBuffer extends Test {
public static void mainx(final String[] argv) {
final Test test;
test = new FileChannelArrayByteBuffer();
test.run(new File(argv[0]));
}
protected long readFile(final File file) {
FileInputStream stream;
stream = null;
try {
final byte[] data;
final FileChannel channel;
final ByteBuffer buffer;
int nRead=0;
final int fileSize;
int sum;
stream = new FileInputStream(file);
data = new byte[(int)file.length()];
buffer = ByteBuffer.wrap(data);
channel = stream.getChannel();
fileSize = (int)file.length();
nRead += channel.read(buffer);
buffer.rewind();
sum = 0;
for(int i = 0; i < fileSize; i++) {
sum += buffer.get();
}
return (sum);
}
catch(final IOException ex) {
ex.printStackTrace();
}
finally {
if(stream != null) {
try {
stream.close();
}
catch(final IOException ex) {
ex.printStackTrace();
}
}
}
return (0);
}
}
class FileChannelAllocateByteBuffer extends Test {
public static void mainx(final String[] argv) {
final Test test;
test = new FileChannelAllocateByteBuffer();
test.run(new File(argv[0]));
}
protected long readFile(final File file) {
FileInputStream stream;
stream = null;
try {
final byte[] data;
final FileChannel channel;
final ByteBuffer buffer;
int nRead=0;
final int fileSize;
int sum;
stream = new FileInputStream(file);
//data = new byte[(int)file.length()];
buffer = ByteBuffer.allocate((int)file.length());
channel = stream.getChannel();
fileSize = (int)file.length();
nRead += channel.read(buffer);
buffer.rewind();
sum = 0;
for(int i = 0; i < fileSize; i++) {
sum += buffer.get();
}
return (sum);
}
catch(final IOException ex) {
ex.printStackTrace();
}
finally {
if(stream != null) {
try {
stream.close();
}
catch(final IOException ex) {
ex.printStackTrace();
}
}
}
return (0);
}
}
class FileChannelAllocateDirectByteBuffer extends Test {
public static void mainx(final String[] argv) {
final Test test;
test = new FileChannelAllocateDirectByteBuffer();
test.run(new File(argv[0]));
}
protected long readFile(final File file) {
FileInputStream stream;
stream = null;
try {
final byte[] data;
final FileChannel channel;
final ByteBuffer buffer;
int nRead=0;
final int fileSize;
int sum;
stream = new FileInputStream(file);
//data = new byte[(int)file.length()];
buffer = ByteBuffer.allocateDirect((int)file.length());
channel = stream.getChannel();
fileSize = (int)file.length();
nRead += channel.read(buffer);
buffer.rewind();
sum = 0;
for(int i = 0; i < fileSize; i++) {
sum += buffer.get();
}
return (sum);
}
catch(final IOException ex) {
ex.printStackTrace();
}
finally {
if(stream != null) {
try {
stream.close();
}
catch(final IOException ex) {
ex.printStackTrace();
}
}
}
return (0);
}
}
class FileChannelAllocateByteBuffer_StaticBuffer extends Test {
public static void mainx(final String[] argv) {
final Test test;
test = new FileChannelAllocateByteBuffer_StaticBuffer();
test.run(new File(argv[0]));
}
protected long readFile(final File file) {
FileInputStream stream;
stream = null;
try {
final byte[] data;
final FileChannel channel;
int nRead=0;
final int fileSize;
int sum;
stream = new FileInputStream(file);
//data = new byte[(int)file.length()];
StaticBuffer.clear();
StaticBuffer.limit((int)file.length());
channel = stream.getChannel();
fileSize = (int)file.length();
nRead += channel.read(StaticBuffer);
StaticBuffer.rewind();
sum = 0;
for(int i = 0; i < fileSize; i++) {
sum += StaticBuffer.get();
}
return (sum);
}
catch(final IOException ex) {
ex.printStackTrace();
}
finally {
if(stream != null) {
try {
stream.close();
}
catch(final IOException ex) {
ex.printStackTrace();
}
}
}
return (0);
}
}
class FileChannelAllocateDirectByteBuffer_StaticBuffer extends Test {
public static void mainx(final String[] argv) {
final Test test;
test = new FileChannelAllocateDirectByteBuffer_StaticBuffer();
test.run(new File(argv[0]));
}
protected long readFile(final File file) {
FileInputStream stream;
stream = null;
try {
final byte[] data;
final FileChannel channel;
int nRead=0;
final int fileSize;
int sum;
stream = new FileInputStream(file);
//data = new byte[(int)file.length()];
StaticDirectBuffer.clear();
StaticDirectBuffer.limit((int)file.length());
channel = stream.getChannel();
fileSize = (int)file.length();
nRead += channel.read(StaticDirectBuffer);
StaticDirectBuffer.rewind();
sum = 0;
for(int i = 0; i < fileSize; i++) {
sum += StaticDirectBuffer.get();
}
return (sum);
}
catch(final IOException ex) {
ex.printStackTrace();
}
finally {
if(stream != null) {
try {
stream.close();
}
catch(final IOException ex) {
ex.printStackTrace();
}
}
}
return (0);
}
}
従来のアプローチでは、速度が制限されます。あるアプローチから次のアプローチへの大きな違いがわかるかどうかはわかりません。
操作全体を高速化できるビジネス上のトリックに集中します。
たとえば、すべてのファイルを読み取って、それぞれの元のファイルのタイムスタンプを持つ単一のファイルに保存した場合、実際にファイルを開かずにファイルが変更されたかどうかを確認できます。 (つまり、単純なキャッシュ)。
問題がGUIの迅速な起動であった場合、最初の画面が表示された後にバックグラウンドスレッドでファイルを開く方法を見つけることができます。
OSはファイルにかなり適しています。これがバッチプロセスの一部である場合(ユーザーI / Oがない場合)、Javaを起動する前に、何かを使用してすべてのファイルを1つの大きなファイルに追加するバッチファイルから開始できますこのように:
echo "file1" > file.all
type "file1" >> file.all
echo "file2" >> file.all
type "file2" >> file.all
その後、file.allを開くだけです(これがどれほど速くなるかはわかりませんが、たった今述べた条件に対する最速のアプローチでしょう)
多くの場合、速度の問題を解決するには、視点を少し拡大し、新しいパラメーターを使用して解決策を完全に再考する必要がある場合が多いと思います。通常、既存のアルゴリズムの変更は、読みやすさを犠牲にして速度をわずかに向上させるだけです。
Commons IO FileUtils.readFileToString(File)などの標準ツールを使用して、1秒以内にすべてのファイルを読み取ることができるはずです
writeStringToFile(File、String)を使用して、変更されたファイルも保存できます。
http:/ /commons.apache.org/io/api-release/index.html?org/apache/commons/io/FileUtils.html
ところで:50は多数のファイルではありません。典型的なPCは100K以上のファイルを持つことができます。