读取阵列中文件数据的最快方法(Java)

读取阵列中文件数据的最快方法(Java),java,performance,Java,Performance,请看以下链接: 这就是为什么我总是喜欢使用数组而不是(数组)列表的原因之一。 不过,这让我想到了内存管理和速度 因此,我得出以下问题: 当您不知道文件的大小(/number of entries)时,存储文件数据的最佳方法是什么(其中best被定义为“最少的计算时间”) 下面,我将介绍3种不同的方法,我想知道哪种方法最好,为什么。为了澄清问题,让我们假设我必须以一个数组结束。另外,假设.txt文件中的每一行只有一个条目(/1个字符串)。另外,为了限制问题的范围,我将把这个问题仅限于Java 假

请看以下链接:

这就是为什么我总是喜欢使用数组而不是(数组)列表的原因之一。 不过,这让我想到了内存管理和速度

因此,我得出以下问题:

当您不知道文件的大小(/number of entries)时,存储文件数据的最佳方法是什么(其中best被定义为“最少的计算时间”)

下面,我将介绍3种不同的方法,我想知道哪种方法最好,为什么。为了澄清问题,让我们假设我必须以一个数组结束。另外,假设.txt文件中的每一行只有一个条目(/1个字符串)。另外,为了限制问题的范围,我将把这个问题仅限于Java

假设我们要从名为
words.txt的文件中检索以下信息:

Hello
I 
am
a
test 
file
方法1-双重危险

File read = new File("words.txt");
Scanner in = new Scanner(read);

int counter = 0;

while (in.hasNextLine())
{
    in.nextLine();
    counter++;
}

String[] data = new String[counter];

in = new Scanner(read);

int i = 0;

while (in.hasNextLine())
{
    data[i] = in.nextLine();
    i++;
}
方法2-清晰但冗余

File read = new File("words.txt");
Scanner in = new Scanner(read);

ArrayList<String> temporary = new ArrayList<String>();

while (in.hasNextLine())
{
    temporary.add(in.nextLine());
}

String[] data = new String[temporary.size()];

for (int i = 0; i < temporary.size(); i++)
{
    data[i] = temporary.get(i);
}
如果您有其他方法(更好),请在下面提供。 此外,如果需要,请随时调整我的代码


在阵列中存储数据的最快方法是以下方法:

File read = new File("words.txt");
Scanner in = new Scanner(read);

ArrayList<String> temporary = new ArrayList<String>();

while (in.hasNextLine()) {
    temporary.add(in.nextLine());
}

String[] data = temporary.toArray(new String[temporary.size()]);
File read=新文件(“words.txt”);
扫描仪输入=新扫描仪(读取);
ArrayList temporary=新的ArrayList();
while(在.hasNextLine()中){
temporary.add(in.nextLine());
}
String[]data=temporary.toArray(新字符串[temporary.size()]);
对于Java 7+:

Path loc = Paths.get(URI.create("file:///Users/joe/FileTest.txt"));
List<String> lines = Files.readAllLines(loc, Charset.defaultCharset());
String[] array = lines.toArray(new String[lines.size()]);
List<String> lines = Files.readAllLines(file, charset);
String[] array = lines.toArray(new String[lines.size()]);
Path loc=Path.get(URI.create(“file:///Users/joe/FileTest.txt"));
列表行=Files.readAllLines(loc,Charset.defaultCharset());
字符串[]数组=lines.toArray(新字符串[lines.size()]);

我想最好的方法就是更快

我将使用方法2,但使用以下提供的方法创建数组:

甚至更简单(Java 7+):


编辑:

对于,结果是一致的:

基准均值
方法1 608649.322
方法2 34167.101
方法3 63410.496
方法4 65552.79

我想最好的方法就是更快

我将使用方法2,但使用以下提供的方法创建数组:

甚至更简单(Java 7+):


编辑:

对于,结果是一致的:

基准均值
方法1 608649.322
方法2 34167.101
方法3 63410.496
方法4 65552.79

如果从文件中读取数据,瓶颈将是文件读取(IO)阶段。在几乎所有情况下,处理它所花费的时间都是微不足道的。所以,做正确和安全的事情。首先你要做对;那你就快点


如果您不知道文件的大小,则必须具有某种动态扩展的数据结构。这就是
ArrayList
的含义。您自己编写的代码不可能比JavaAPI中如此重要的一部分更有效或正确。因此,只需使用
ArrayList
:选项2。

如果您正在从文件读取数据,瓶颈将是文件读取(IO)阶段。在几乎所有情况下,处理它所花费的时间都是微不足道的。所以,做正确和安全的事情。首先你要做对;那你就快点

如果您不知道文件的大小,则必须具有某种动态扩展的数据结构。这就是
ArrayList
的含义。您自己编写的代码不可能比JavaAPI中如此重要的一部分更有效或正确。所以只需使用
ArrayList
:选项2。

我会使用

File File=新文件(“words.txt”);
列表行=Files.readLines(file,Charset.defaultCharset());
//如果它确实必须是一个数组:
String[]数组=lines.toArray(新字符串[0]);
我会使用

File File=新文件(“words.txt”);
列表行=Files.readLines(file,Charset.defaultCharset());
//如果它确实必须是一个数组:
String[]数组=lines.toArray(新字符串[0]);

这里给出了与所有源代码的非常好的比较

摘要:

要获得最佳Java读取性能,需要记住四件事:

  • 通过一次读取一个数组而不是一个字节来最小化I/O操作。8Kbyte数组大小合适
  • 通过以下方式最小化方法调用 一次获取一个数组的数据,而不是一次获取一个字节的数据。使用数组 索引以获取数组中的字节
  • 如果不需要线程安全,请最小化线程同步锁。要么做 减少对线程安全类的方法调用,或使用非线程安全类 类,如FileChannel和MappedByteBuffer
  • 最大限度地减少数据复制 在JVM/OS、内部缓冲区和应用程序阵列之间。使用 具有内存映射的FileChannel,或直接数组或包装数组 拜特伯弗
希望有帮助

编辑

我想做这样的事:

File read = new File("words.txt");
Scanner in = new Scanner(read);    
List<String> temporary = new LinkedList<String>();

while (in.hasNextLine()) {
    temporary.add(in.nextLine());
}

String[] data = temporary.toArray(new String[temporary.size()]);
File read=新文件(“words.txt”);
扫描仪输入=新扫描仪(读取);
List temporary=新建LinkedList();
while(在.hasNextLine()中){
temporary.add(in.nextLine());
}
String[]data=temporary.toArray(新字符串[temporary.size()]);

主要区别在于只读取一次数据(与其他两种方法相反),并且在linkedlist中添加非常便宜+无需对行执行额外操作(如拆分)-此处不要使用arraylist

此处与所有源代码进行了非常好的比较

List<String> lines = Files.readAllLines(yourFile, charset);
String[] arr = lines.toArray(new String[lines.size()]);
摘要:

要获得最佳Java读取性能,需要记住四件事:

  • 通过一次读取一个数组而不是一个字节来最小化I/O操作。8Kbyte数组大小合适
  • 通过以下方式最小化方法调用 一次获取一个数组的数据,而不是一次获取一个字节的数据。使用数组 索引以获取数组中的字节
  • 如果不需要线程安全,请最小化线程同步锁。要么做 对线程安全类(u)的方法调用更少
    File file = new File("words.txt");
    List<String> lines = Files.readLines(file, Charset.defaultCharset());
    // If it really has to be an array:
    String[] array = lines.toArray(new String[0]);
    
    File read = new File("words.txt");
    Scanner in = new Scanner(read);    
    List<String> temporary = new LinkedList<String>();
    
    while (in.hasNextLine()) {
        temporary.add(in.nextLine());
    }
    
    String[] data = temporary.toArray(new String[temporary.size()]);
    
    List<String> lines = Files.readAllLines(yourFile, charset);
    String[] arr = lines.toArray(new String[lines.size()]);