İtibar puanım biraz atlayana kadar benzer bir soruyu yayınlamam gerekiyordu (kim beni çarptıysa!).
Tüm bu çözümler, arabelleksiz (ham) arabirimi kullanarak, bytearrays kullanarak ve kendi arabelleklemenizi yaparak, bu işlemi önemli ölçüde daha hızlı yapmanın bir yolunu yok sayar. (Bu yalnızca Python 3 için geçerlidir. Python 2'de, ham arabirim varsayılan olarak kullanılabilir veya kullanılmayabilir, ancak Python 3'te varsayılan olarak Unicode'u kullanırsınız.)
Zamanlama aracının değiştirilmiş bir sürümünü kullanarak, aşağıdaki kodun sunulan çözümlerden daha hızlı (ve marjinal olarak daha pythonic) olduğuna inanıyorum:
def rawcount(filename):
f = open(filename, 'rb')
lines = 0
buf_size = 1024 * 1024
read_f = f.raw.read
buf = read_f(buf_size)
while buf:
lines += buf.count(b'\n')
buf = read_f(buf_size)
return lines
Ayrı bir jeneratör işlevi kullanarak, bu daha hızlı bir görüntü sağlar:
def _make_gen(reader):
b = reader(1024 * 1024)
while b:
yield b
b = reader(1024*1024)
def rawgencount(filename):
f = open(filename, 'rb')
f_gen = _make_gen(f.raw.read)
return sum( buf.count(b'\n') for buf in f_gen )
Bu tamamen itertools kullanarak satır içi jeneratör ifadeleri ile yapılabilir, ancak oldukça garip görünüyor:
from itertools import (takewhile,repeat)
def rawincount(filename):
f = open(filename, 'rb')
bufgen = takewhile(lambda x: x, (f.raw.read(1024*1024) for _ in repeat(None)))
return sum( buf.count(b'\n') for buf in bufgen )
İşte zamanlamalarım:
function average, s min, s ratio
rawincount 0.0043 0.0041 1.00
rawgencount 0.0044 0.0042 1.01
rawcount 0.0048 0.0045 1.09
bufcount 0.008 0.0068 1.64
wccount 0.01 0.0097 2.35
itercount 0.014 0.014 3.41
opcount 0.02 0.02 4.83
kylecount 0.021 0.021 5.05
simplecount 0.022 0.022 5.25
mapcount 0.037 0.031 7.46