Nach einem Kommentar zur Shuf-Antwort mischte er 78 000 000 000 Zeilen in weniger als einer Minute.
Herausforderung angenommen...
Zuerst brauchte ich eine Datei mit 78.000.000.000 Zeilen:
seq 1 78 | xargs -n 1 -P 16 -I% seq 1 1000 | xargs -n 1 -P 16 -I% echo "" > lines_78000.txt
seq 1 1000 | xargs -n 1 -P 16 -I% cat lines_78000.txt > lines_78000000.txt
seq 1 1000 | xargs -n 1 -P 16 -I% cat lines_78000000.txt > lines_78000000000.txt
Das gibt mir eine Datei mit 78 Milliarden Zeilenumbrüchen ;-)
Nun zum Shuf-Teil:
$ time shuf -n 10 lines_78000000000.txt
shuf -n 10 lines_78000000000.txt 2171.20s user 22.17s system 99% cpu 36:35.80 total
Der Engpass war die CPU, die nicht mehrere Threads verwendete. Sie steckte 1 Kern zu 100% fest, die anderen 15 wurden nicht verwendet.
Python ist das, was ich regelmäßig benutze, also werde ich es verwenden, um dies schneller zu machen:
#!/bin/python3
import random
f = open("lines_78000000000.txt", "rt")
count = 0
while 1:
buffer = f.read(65536)
if not buffer: break
count += buffer.count('\n')
for i in range(10):
f.readline(random.randint(1, count))
Das brachte mich knapp eine Minute:
$ time ./shuf.py
./shuf.py 42.57s user 16.19s system 98% cpu 59.752 total
Ich habe dies auf einem Lenovo X1 extreme 2. Generation mit dem i9 und Samsung NVMe gemacht, was mir viel Lese- und Schreibgeschwindigkeit gibt.
Ich weiß, dass es schneller werden kann, aber ich werde etwas Raum lassen, um andere auszuprobieren.
Zeilenzählerquelle : Luther Blissett