Arrays 将文件读入d中的行数组

Arrays 将文件读入d中的行数组,arrays,file-io,d,Arrays,File Io,D,将文本文件读入行数组的正确方法是什么?我在罗塞塔石上发现了以下内容: string[] readLines(string filename) { auto f = File(filename); scope(exit) f.close(); string[] lines; foreach (str; f.byLine) { lines ~= str.idup; } return lines; } 但它看起来像是每行调整一个数组大小,这是非常低效的。我可以跟踪

将文本文件读入行数组的正确方法是什么?我在罗塞塔石上发现了以下内容:

string[] readLines(string filename) {
  auto f = File(filename);
  scope(exit) f.close();
  string[] lines;

  foreach (str; f.byLine) {
    lines ~= str.idup;
  }

  return lines;
}
但它看起来像是每行调整一个数组大小,这是非常低效的。我可以跟踪读取的行数,并通过标准的倍增方法调整数组大小

  int i = 0;
  foreach (str; f.byLine) {
    if (lines.length <= i + 1) {
      lines.length = lines.length * 2 + 1;
    }
    lines[i] = str.idup;
    i++;
  }
  lines.length = i;
inti=0;
foreach(str;f.byLine){

如果(lines.length事实上,当D的空间用完时,它将使阵列的保留空间翻倍,因此您不需要手动操作。关于D的阵列有很多信息,您可能会在开始时得到大量的重新分配,但随着阵列的增长,其容量应该会增加,这样就不太可能分配更多的空间您可以打印出阵列的
容量
属性,看看它是如何增长的

但是,如果您特别担心附加性能,那么您可能应该使用,在这种情况下,您的代码将如下所示:

string[] readLines(string filename)
{
    auto file = File(filename);
    auto lines = appender!(string[]);

    foreach(line; file.byLine())
        lines.put(to!string(line));

    return lines.data;
}
Appender
旨在提高附加效率,并将利用各种技巧使附加效率高于
~=
本身。

也许:

import std.algorithm;
import std.array;
import std.file;

string[] readLines(string input)
{
    Appender!(string[]) result;
    foreach (line; input.splitter("\n"))
        result.put(line);
    return result.data;
}

void main()
{
    string input = cast(string)std.file.read("test.d");
    string[] lines = readLines(input);
}

它应该足够快,因为结果只是创建预加载输入字符串的片段,而不是分配新数组(除了片段本身的分配之外,请查看指针+长度字段).

我读了一遍,在附加到ArrayEah时,它没有说明任何内部大小调整策略,我只是注意到了这一点,但我知道它是如何工作的。更详细地说,D实际上是以两个大小的幂次块分配内存的,所以如果数组的大小超过32字节,它就会重新分配到64字节的块字节。如果你真的很担心,文档说你可以使用phobos的
.capacity
属性来确定在调整大小之前可以使用多少空间。dlang上还有一篇关于切片的文章,这很有趣。它有一个关于分配的部分。