Büyük kelime listesindeki kopyaları silmenin en hızlı yolu?


14

Büyük bir kelime listesini tekilleştirmem gerekiyor. Birkaç komut denedim ve Linux'taki en hızlı `` uniq '' aracında biraz araştırma yaptım ve büyük bir çoklu GB metin dosyasında yinelenen satırları nasıl kaldırabilirim? bir kelime listesini tekilleştirmenin en hızlı yolunun kullanıldığını açıklıyorlar awk.

awk  --> O(n) ?
sort --> O(n log n) ?

Ancak bunun doğru olmadığını gördüm. İşte test sonuçlarım:

time sort -u input.txt -o output.txt 
real    0m12.446s  
user    0m11.347s  
sys 0m0.906s**


time awk '!x[$0]++' input.txt > output.txt
real    0m47.221s  
user    0m45.419s  
sys 0m1.260s

Yani kullanmak sort -u3,7 kat daha hızlı. Bu neden? Tekilleştirme yapmak için daha hızlı bir yöntem var mı?

*********** Güncelleme ********

Birinin yorumlarda belirttiği gibi, kelime listemin zaten bir dereceye kadar sıralanmış olması olabilir. Bu olasılığı hariç tutmak için random_number_wordlist_generator.py kullanarak iki kelime listesi oluşturdum .

List1 = 7 Mb  
List2 = 690 Mb

**Results AWK:**  
***List1***  
real    0m1.643s  
user    0m1.565s  
sys     0m0.062s

***List2***  
real    2m6.918s  
user    2m4.499s  
sys     0m1.345s

**Results SORT:**  
***List1***  
real    0m0.724s  
user    0m0.666s  
sys     0m0.048s

***List2***  
real    1m27.254s  
user    1m25.013s  
sys     0m1.251s

Girdi verileriniz zaten sıralanmış olabilir mi?
iruvar

Rakamlarla rastgele bir liste oluşturacağım ve sadece emin olmak için kontrol
edeceğim

2
Büyük O gösterimi, giriş uzunluğu sonsuza yaklaştığında ne olduğu ile ilgilidir: size büyük girdiyle ölçeklenen bir algoritma olduğunu söyler. Bazı algoritmalar küçük girdi boyutlarında daha iyi çalışır.
ctrl-alt-delor

1
Karlpy, hangi sırayla yerine getirdin, önce awk veya sıralama? Dosya önbelleğe alma nedeniyle fark yaratabilir
iruvar

1
@karlpy: "Dosya adını değiştirdim ..." Dosyayı yeniden adlandırdığınız anlamına gelirse, bu yeterince iyi değil. Bir dosyayı yeniden adlandırmak, aynı eski veri bloklarını gösteren eski inode ile yeni bir ad ilişkilendirir. Önbelleğe alınmışlarsa, hala önbelleğe alınırlar. ISTM çok daha iyi bir teknik (1) dosyanın bir kopyasını yapmak ve sonra (2) tek bir dosya ve (3) üzerine bir komutu çalıştırmak diğer dosyadaki diğer komutunu çalıştırın.
Scott

Yanıtlar:


4

Yanlış soruyu soruyorsunuz veya soruyu yanlış ve yanlış yığın halinde soruyorsanız, bu, programlama / yığın taşması sırasında insanların awk ve sort içinde kullanılan algoritmalara göre size cevap vermesini istemek daha iyi bir soru.

PS: ayrıca nawk, mawk ve gawk ile bize "bölge içine" biraz daha detay vermek için gerekli;) ve min, max, avg ve standart sapma ile her biri 100 kez gibi çalışır.

Eldeki soruya geri dönersek, CompSci 210'dan, kullanılan algoritmalar ile ilgilidir. Sırala, dosyaları geçici diskte diske kaydetmek için vurduğu boyutlara ve bellek kısıtlamalarına bağlı olarak, bellek bittiğinde birleştirme sıralaması için birkaçını kullanır ve ne olduğunu görmek için kaynak koduna bakmanız gerekir. belirli sort (1) komutu çalıştırdığınız işletim sisteminde kullanır, ancak deneyimden belleğe olabildiğince yüklenir, üzerine hızlı sıralama yapın, diske yazın, tekrar yıkayın ve sonunda küçük birleştirilmiş dosyaları birleştirme tür yapacak. Burada parçalar için O (n * log2 (N)) ve ardından yaklaşık O (n * log (n)) birleştirme işlemi olacak

awk: x [$ 0] ++ mekanizması karma kullanmak için "varsayalım" dır. ANCAK, hash, sözde bir O (1) "arama" işlemi ile ilgili sorun, çarpışmalar ve çarpışmaların ele alınması. Bu, veriler iyi yayılmadığında, kovaları vb. Doldurmadığında ve büyük listelerde bir soruna neden olabilir ve çarpışmaların işlenmesi doğru yapılmazsa karma büyük bir hafıza sorunu olabilir (ve hash algoritmalarını beklenen veriler için ayarlayın) ve daha sonra gerçek hash fonksiyonlarının performansına bakmanız gerekir ve daha sonra O (1) ekler (O, log (n)) için O'ya (log (n)) daha yakın olabilir. (1) ilk arama için ve eğer yoksa, O (log (n)) olabilir ve n * O (1) bir * O (log (n)) = > O (n * log (n)), bir şeyleri "yorumlanmış" bir şekilde yaptığınızdan bahsetmiyorum bile :)


awkayrıca ve en önemlisi, her satırı varsayılan olarak boşluklara böler. Bu zaman alır.
Kusalananda

@Kusalananda, RAM ve disk G / Ç sınırlarına çarptığınızda daha büyük şemada çok az yük;)
Hvisage

0

sort -uBazı ciddi komut dosyası dilini (Python / Perl / Raku, muhtemelen sıralamadan sonra) kırmadan önce ve muhtemelen en yüksek hıza olan mutlak ihtiyacı gördükten sonra görev için nasıl kullanılacağını (muhtemelen daha fazla anahtarla!) diğer alternatifleri düşünün.


-2

Hız farkı 'sort' bir komut ( link ), 'awk' ise bir programlama dilidir ( link ).

'sort' komutu girdi ve geri çıktı alır. Oysa 'awk' önce kodu (terminal komutu) yorumlayan sonra üzerinde işlem yapmaya başlayan bir programlama dilidir. Bu kadar basit.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.