Ksh93 nasıl bu kadar hızlı?


9

Bu nedenle, genel olarak, sedmetin işlemeyi - özellikle büyük dosyalar için - arama eğilimindeyim ve genellikle kabuğun kendisinde bu tür şeyler yapmaktan kaçınırım.

Bence bu değişebilir. At etrafında alay man kshve bunu fark ettim:

<#pattern     Seeks forward to the beginning of the
              next line containing pattern.

<##pattern    The same as <# except that  the  por
              tion  of  the file that is skipped is
              copied to standard output.

Gerçek dünyadaki kullanışlılığa şüpheyle bakmaya karar verdim. Yaptım:

seq -s'foo bar
' 1000000 >file

... bir milyon veri satırı için:

1foo bar
...
999999foo bar
1000000

... ve şuna sedbenzer:

p='^[^0-8]99999.*bar'
for c in "sed '/$p/q'" "ksh -c ':<##@(~(E)$p)'"    
do </tmp/file eval "time ( $c )"
done | wc -l

Bu nedenle, her iki komut da 999999foo çubuğuna kadar olmalı ve kalıp eşleştirme uygulaması, bunu yapabilmek için her satırın en azından başlangıcını ve sonunu değerlendirmelidir. Ayrıca, ilk karakteri ihmal edilmiş bir desene karşı doğrulamaları gerekir. Bu basit bir şey, ama ... Sonuçlar beklediğim gibi değildi:

( sed '/^[^0-8]99999.*bar/q' ) \
    0.40s user 0.01s system 99% cpu 0.419 total
( ksh -c ':<##@(~(E)^[^0-8]99999.*bar)' ) \
    0.02s user 0.01s system 91% cpu 0.033 total
1999997

kshburada ERE ve sedbir BRE kullanır . Aynı şeyi daha kshönce bir kabuk deseni ile yaptım ama sonuçlar farklı değildi.

Her neyse, bu oldukça önemli bir tutarsızlık - 10 kat kshdaha iyi sed. Daha önce David Korn'un kendi io lib'ini yazdığını ve uyguladığını okumuştum ksh- muhtemelen bu ilgili mi? - ama onun hakkında hiçbir şey bilmiyorum. Kabuk bunu nasıl iyi yapıyor?

Benim için daha da şaşırtıcı olanı ksh, ofsetini gerçekten istediğiniz yerde bırakıyor. Almak için (neredeyse) aynı out (GNU) sed kullanmak zorunda -u- çok yavaş .

İşte bir grepv. kshTesti:

1000000         #grep + head
( grep -qm1 '^[^0-8]99999.*bar'; head -n1; ) \
    0.02s user 0.00s system 90% cpu 0.026 total
999999foo bar   #ksh + head
( ksh -c ':<#@(~(E)^[^0-8]99999.*bar)'; head -n1; )  \
    0.02s user 0.00s system 73% cpu 0.023 total

kshgrepburada atıyor - ama her zaman değil - hemen hemen bağlılar. Yine de, bu oldukça mükemmel ve ksh lookahead - head'in girişi maçtan önce başlıyor .

Sanırım gerçek olamayacak kadar iyi görünüyor. Bu komutlar kaputun altında ne yapıyor?

Oh, ve görünüşe göre burada bir alt kabuk bile yok:

ksh -c 'printf %.5s "${<file;}"'

patternbir düzenli ifade ya da daha basit kabuk desen?
muru

Muru - İkisi de olabilir, ama bunları değiştirmede çok iyi değilim. Örnekte bu bir kabuk deseni - varsayılan.
mikeserv

@muru - Bir normal ifadeyle bir tane ekledim.
mikeserv

Yanıtlar:


8

Ksh sadece sfio kullanmakla kalmaz, aynı zamanda kendi özel bellek ayırıcısını kullanır.

Bununla birlikte, benim tahminim sfio bu durumda fark yaratıyor. Ben sadece strace altında örnek çalıştırmak için çalıştı ve sed ~ 3400 kez (4 KB blok) yaparken ksh çağrıları okuma / yazma ~ 200 kez (65 KB blok) görebilirsiniz. Sed -u ile dizüstü bilgisayarım neredeyse eridi, okumalar bayt başına yapılır ve satır başına yazar. Ksh basit lseek kullanır. Grep ~ 400 defa okundu (32 KB blok).


Evet - arabelleksiz kalbin zayıflığı için değil. kshRegex motorunun io kadar verimli olup olmadığını merak ediyorum. Her neyse, cevap için çok teşekkürler. Dizüstü bilgisayarınızdan özür dilerim. Peki, özel bellek ayırıcısı ne olacak? Bundan daha fazlasý var mý?
mikeserv

1
Üzgünüm hayır. Tabii ki & t web sitesinden kaynak kodu indirebilirsiniz, ama hepsi bu. Kütüphaneye AST denir ve allocator, regex motoru ve daha birçok şey içerir. Bu nedenle, tüm bu şeylerin kombinasyonunun ksh'ı daha hızlı hale getirmesi tamamen mümkündür.
Miroslav Franc


Teşekkür ederim - bu da umut verici görünüyor: AST yazılım koleksiyonunda bulunan bileşenlerden bazıları şunlardır: POSIX komutları Standart POSIX komutlarının çoğu AST koleksiyonunda bulunur. Birçoğu, ksh'a performansı önemli ölçüde artıran yerleşik komut olarak eklenebilen kütüphane işlevleri olarak kodlanmıştır. - Şimdi nasıl inşa
edeceğimi bulmalıyım

1
@mikeserv ksh, Phong Vo'nun vmalloc ayırıcısını kullanmak için inşa edilebilir . Dergi makaleleri bu linkten edinilebilir.
Mark Plotnick
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.