Улучшение линейных операций ввода-вывода в D

Мне нужно обрабатывать множество средних и больших файлов (от нескольких сотен МБ до ГБ) по-разному, поэтому меня интересуют стандартные подходы D для итерации по линиям. Идиома foreach(line; file.byLine()) видимому, соответствует счету и является приятным и понятным, однако производительность кажется менее идеальной.

Например, ниже представлены три тривиальные программы в Python и D для итерации по строкам файла и подсчета строк. Для файла размером ~ 470 МБ (строки ~ 3.6M) я получаю следующие тайминги (лучше всего из 10):

D раз:

 real 0m19.146s user 0m18.932s sys 0m0.190s 

Время Python (после EDIT 2 , см. Ниже):

 real 0m0.924s user 0m0.792s sys 0m0.129s 

Вот версия D, скомпилированная с dmd -O -release -inline -m64 :

 import std.stdio; import std.string; int main(string[] args) { if (args.length < 2) { return 1; } auto infile = File(args[1]); uint linect = 0; foreach (line; infile.byLine()) linect += 1; writeln("There are: ", linect, " lines."); return 0; } 

И теперь соответствующая версия Python:

 import sys if __name__ == "__main__": if (len(sys.argv) < 2): sys.exit() infile = open(sys.argv[1]) linect = 0 for line in infile: linect += 1 print "There are %d lines" % linect 

EDIT 2 : я изменил код Python, чтобы использовать более идиоматический for line in infile как это предлагается в комментариях ниже, что приводит к еще большему ускорению для версии Python, которая теперь приближается к скорости стандартного вызова wc -l к средству wc Unix.

Любые советы или указатели на то, что я могу сделать неправильно в D, что дает такую ​​плохую производительность?

EDIT : И для сравнения, вот версия D, которая выдает byLine() из окна и сразу же всасывает все данные в память, а затем разбивает данные на строки post-hoc. Это дает лучшую производительность, но по-прежнему примерно в 2 раза медленнее, чем у Python.

 import std.stdio; import std.string; import std.file; int main(string[] args) { if (args.length < 2) { return 1; } auto c = cast(string) read(args[1]); auto l = splitLines(c); writeln("There are ", l.length, " lines."); return 0; } 

Тайминги для этой последней версии следующие:

 real 0m3.201s user 0m2.820s sys 0m0.376s