Saya harus memposting ini pada pertanyaan yang sama sampai skor reputasi saya melonjak sedikit (terima kasih kepada siapa pun yang menabrak saya!).
Semua solusi ini mengabaikan satu cara untuk membuat ini berjalan jauh lebih cepat, yaitu dengan menggunakan antarmuka (mentah) unbuffered, menggunakan bytearrays, dan melakukan buffering Anda sendiri. (Ini hanya berlaku dalam Python 3. Dalam Python 2, antarmuka mentah mungkin atau mungkin tidak digunakan secara default, tetapi dalam Python 3, Anda akan default ke Unicode.)
Menggunakan versi modifikasi dari alat penghitung waktu, saya percaya kode berikut ini lebih cepat (dan sedikit lebih pythonic) daripada salah satu solusi yang ditawarkan:
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
Menggunakan fungsi generator terpisah, ini menjalankan smidge lebih cepat:
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 )
Ini dapat dilakukan sepenuhnya dengan ekspresi generator secara in-line menggunakan itertools, tetapi terlihat sangat aneh:
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 )
Inilah waktu saya:
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