J'ai dû poster ceci sur une question similaire jusqu'à ce que mon score de réputation ait un peu augmenté (merci à celui qui m'a cogné!).
Toutes ces solutions ignorent une façon d'accélérer considérablement l'exécution, à savoir en utilisant l'interface non tamponnée (brute), en utilisant des tableaux de bord et en effectuant votre propre mise en mémoire tampon. (Cela ne s'applique qu'à Python 3. Dans Python 2, l'interface brute peut ou non être utilisée par défaut, mais dans Python 3, vous utiliserez par défaut Unicode.)
En utilisant une version modifiée de l'outil de synchronisation, je pense que le code suivant est plus rapide (et légèrement plus pythonique) que toutes les solutions proposées:
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
En utilisant une fonction de générateur séparée, cela fonctionne plus rapidement:
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 )
Cela peut être fait complètement avec des expressions de générateurs en ligne à l'aide d'itertools, mais cela devient assez étrange:
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 )
Voici mes horaires:
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