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

ดังนั้นทั้งสองคำสั่งควรมีแถบสูงสุด999999fooและการใช้รูปแบบการจับคู่ของพวกเขาต้องประเมินอย่างน้อยที่สุดจุดเริ่มต้นและจุดสิ้นสุดของแต่ละบรรทัดเพื่อที่จะทำเช่นนั้น พวกเขายังต้องตรวจสอบถ่านแรกกับรูปแบบเมื่อตะกี้ นี่เป็นสิ่งที่ง่าย แต่ ... ผลลัพธ์ไม่ใช่สิ่งที่ฉันคาดไว้:

( 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 เท่า ฉันเคยอ่านมาก่อนแล้วว่า David Korn เขียน 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อินพุตของlookahead ก่อนเริ่มการแข่งขัน

ฉันคิดว่ามันดีเกินกว่าจะเป็นจริงได้ คำสั่งเหล่านี้ทำอะไรที่แตกต่างกันภายใต้ประทุน?

โอ้และเห็นได้ชัดว่าไม่มีแม้แต่ subshell ที่นี่:

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

การpatternแสดงออกปกติหรือรูปแบบเปลือกง่ายขึ้น?
muru

@muru - อาจเป็นได้ แต่ฉันไม่เก่งในการเปลี่ยนคนรอบตัว ในตัวอย่างเป็นรูปแบบของเชลล์ - ค่าเริ่มต้น
mikeserv

@muru - ฉันเพิ่มหนึ่ง w / a regex
mikeserv

คำตอบ:


8

ksh ไม่เพียงใช้sfioเท่านั้น แต่ยังใช้ตัวจัดสรรหน่วยความจำที่กำหนดเอง

อย่างไรก็ตามฉันเดาว่า sfio สร้างความแตกต่างในกรณีนี้ ฉันพยายามเรียกใช้ตัวอย่างของคุณภายใต้ strace และสามารถเห็นว่า ksh เรียกอ่าน / เขียน ~ 200 ครั้ง (65 KB บล็อก) ในขณะที่ทำมัน ~ 3400 ครั้ง (4 KB บล็อก) ด้วย sed -u แล็ปท็อปของฉันเกือบจะละลายการอ่านจะทำต่อไบต์และเขียนต่อบรรทัด Ksh ใช้ง่าย lseek Grep ใช้ read ~ 400 ครั้ง (32 KB blocks)


ใช่แล้วคนที่ไม่ได้อาบน้ำนั้นไม่ได้มีไว้สำหรับคนใจอ่อน ฉันสงสัยว่าkshเครื่องยนต์ regex ของมีประสิทธิภาพเป็น io หรือไม่ อย่างไรก็ตามขอบคุณมากสำหรับคำตอบ ฉันขอโทษแล็ปท็อปของคุณ อย่างไรก็ตามเกี่ยวกับตัวจัดสรรหน่วยความจำแบบกำหนดเองล่ะ คุณมีอะไรอีกไหม?
mikeserv

1
น่าเศร้าที่ไม่มี คุณสามารถดาวน์โหลดซอร์สโค้ดได้จากเว็บไซต์ & t แต่มันเกี่ยวกับมัน ไลบรารีเรียกว่า AST และมีตัวจัดสรร, โปรแกรม regex และสิ่งอื่น ๆ อีกมากมาย ดังนั้นจึงเป็นไปได้ทั้งหมดที่การรวมกันของทุกสิ่งเหล่านี้ทำให้ ksh เร็วขึ้นมาก
Miroslav Franc


ขอบคุณ - สิ่งนี้มีแนวโน้มเช่นกัน: ส่วนประกอบบางอย่างที่มีอยู่ในชุดซอฟต์แวร์ AST คือ: คำสั่ง POSIX คำสั่ง POSIX มาตรฐานส่วนใหญ่มีอยู่ในคอลเลกชัน AST หลายคนมีรหัสเป็นฟังก์ชั่นห้องสมุดซึ่งสามารถเพิ่มไปยัง ksh เป็นคำสั่งในตัวซึ่งช่วยเพิ่มประสิทธิภาพอย่างมาก - ตอนนี้ฉันแค่ต้องหาวิธีสร้างมันขึ้นมา
mikeserv

1
@mikeserv ksh สามารถสร้างเพื่อใช้ตัวจัดสรรvmallocของ Phong Vo บทความในวารสารมีอยู่ที่ลิงค์นั้น
Mark Plotnick
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.