Як ksh93 так швидко?


9

Тож, загалом, я схильний шукати sedобробку тексту - особливо для великих файлів - і зазвичай уникаю робити подібні речі в самій оболонці.

Я думаю, що це може змінитися. Я ковтав навколо, man kshі я помітив це:

<#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.

Скептично оцінюючи корисність у реальному світі, я вирішив спробувати це. Я зробив:

seq -s'foo bar
' 1000000 >file

... для мільйона рядків даних, які виглядають так:

1foo bar
...
999999foo bar
1000000

... і поставив це проти sed:

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

Таким чином, обидві команди повинні мати до 999999фотосмуга, і їх реалізація відповідності шаблону повинна оцінювати принаймні початок і кінець кожного рядка, щоб це зробити. Вони також повинні перевірити перший знак за запереченим малюнком. Це проста справа, але ... Результати не були такими, які я очікував:

( 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

kshтут використовується ERE і sedBRE. Я робив те ж саме kshі з малюнком оболонки раніше, але результати не відрізнялися.

У всякому разі, це досить суттєва розбіжність - вона kshперевищує sed10 разів. Я раніше читав, що Девід Корн написав власну io lib і реалізує її ksh- можливо, це пов’язано? - але я майже нічого про це не знаю. Як це оболонка робить це так добре?

Ще більш дивовижним для мене є те, що kshдійсно залишає своє зміщення саме там, де ви просите. Щоб отримати (майже) те саме з (GNU), sed ви повинні використовувати -u- дуже повільно .

Ось grepv. kshТест:

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

kshб'є grepтут - але це не завжди - вони дуже прив'язані. Тим не менш, це досить чудово, і ksh забезпечує пошук headданих, починаючи перед його матчем.

Мабуть, це здається занадто гарним, щоб бути правдою. Що ці команди роблять по-різному під кришкою?

О, і, мабуть, тут навіть немає нижньої оболонки:

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

Це patternрегулярний вираз чи простіший шаблон оболонки?
муру

@muru - Це може бути будь-яке, але я не дуже добре змінюю те, що навколо. У прикладі це шаблон оболонки - за замовчуванням.
mikeserv

@muru - я додав один w / a регулярний вираз.
mikeserv

Відповіді:


8

Ksh не тільки використовує sfio, але й використовує власний спеціальний розподільник пам'яті.

Тим не менш, я гадаю, що sfio має значення в цьому випадку. Я просто спробував запустити ваш приклад під напругою, і я можу побачити, що ksh дзвінки читають / пишуть ~ 200 разів (65 КБ блоків), а sed це ~ 3400 разів (4 КБ блоків). З sed -u мій ноутбук майже розплавився, читання робиться за байтом і пише в рядку. Ksh просто використовує lseek. Grep використовує читання ~ 400 разів (32 КБ блоків).


Так - нерозпущений не для слабкого серця. Цікаво, чи kshефективний двигун regex як його io? У будь-якому випадку, дуже дякую за відповідь. Мої вибачення за ваш ноутбук. А як щодо користувацького алокатора пам'яті? Чи є у вас більше з цього приводу?
mikeserv

1
На жаль, ні. Ви, звичайно, можете завантажити вихідний код з веб-сайту & t, але це стосується цього. Бібліотека називається AST і містить аллокатор, двигун регулярного виведення та багато іншого. Тож цілком можливо, що комбінація всіх цих речей робить ksh набагато швидшими.
Мирослав Франк


Дякую - це виглядає також багатообіцяюче: Деякі компоненти, доступні в колекції програмного забезпечення AST, це: команди POSIX Більшість стандартних команд POSIX доступні в колекції AST. Багато хто кодується як бібліотечні функції, які можна додати до ksh як вбудовану команду, що значно підвищує продуктивність. - Тепер я лише повинен розібратися, як його побудувати,
mikeserv

1
@mikeserv ksh можна побудувати для використання vmalloc- розподільника Phong Vo . Статті в журналі доступні за цим посиланням.
Марк Плотнік
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.