Golang: Comment puis-je déterminer le nombre de lignes dans un fichier de manière efficace?
Dans Golang, je suis à la recherche d'un moyen efficace de déterminer le nombre de lignes d'un fichier.
Bien sûr, je suis toujours en boucle dans tout le fichier, mais ne semble pas très efficace.
file, _ := os.Open("/path/to/filename")
fileScanner := bufio.NewScanner(file)
lineCount := 0
for fileScanner.Scan() {
lineCount++
}
fmt.Println("number of lines:", lineCount)
Est-il mieux (plus rapide, moins coûteux) de façon à trouver le nombre de lignes d'un fichier?
- Autant que je sache, que je sais que c'est la seule façon, dans n'importe quelle langue.
- Yup. Vous pouvez obtenir des octets en temps constant, mais pas les lignes.
Vous devez vous connecter pour publier un commentaire.
Ici est un moyen plus rapide de la ligne de compteur à l'aide de
bytes.Count
pour trouver les caractères de saut de ligne.C'est plus rapide parce qu'il emporte toute la logique supplémentaire et de mise en mémoire tampon nécessaire pour retourner un ensemble de lignes, et profite d'un peu de montage optimisé des fonctions offertes par des octets d'un paquet de rechercher les caractères d'un octet tranche.
Plus les tampons de l'aide ici, surtout avec de gros fichiers. Sur mon système, avec le fichier que j'ai utilisé pour le test, un 32k de mémoire tampon a été le plus rapide.
et de l'indice de référence de sortie:
wc
, qui stipule:A line is defined as a string of characters delimited by a <newline> character
. Si vous voulez une fonction pour compter incomplètes en ligne, vous pouvez le faire, mais il ferait cet exemple un peu moins claire.wc -l
. J'ai testé le comptage de 1,6 GO fichier journal avec 11,6 millions de lignes. La première fois que j'ai compté les lignes à l'aidewc -l
il a fallu plusieurs secondes car le fichier est mis en cache. Après quewc -l
pris entre 0.387 et 0.422 secondes pour compter les lignes../linecounter
compte le fichier dans entre 0.407 et à 0,425 secondes. Très respectable à mon avis.Le moyen le plus efficace que j'ai trouvé est à l'aide de IndexByte de l'octet du paquet, il est au moins quatre fois plus rapide que l'utilisation
bytes.Count
et en fonction de la taille de la mémoire tampon, il utilise beaucoup moins de mémoire.De référence
N'est pas l'approche qui est considérablement plus rapide que le vôtre, il n'y a pas de méta-données sur le nombre de lignes d'un fichier. Vous pourriez atteindre un peu de vitesse par manuellement à la recherche pour le saut de ligne-personnages:
\n
.bufio.Scanner
. Remplacement de la gamme de boucle avecbytes.Count
des vitesses jusqu'considérablement si (octets.Le comte a un ASM version de IndexByte)