grep ของ Unix ทำงานได้เร็วขึ้นด้วยข้อความค้นหาที่ยาวหรือสั้นหรือไม่


8

มันเร็วกว่าที่จะมองหาคำค้นหายาวหรือสั้น? หรือส่งผลกระทบต่อความเร็วเลยหรือ? กล่าวอีกนัยหนึ่งคุณควรสร้างข้อความค้นหาที่แน่นอนที่สุดเท่าที่จะเป็นไปได้หรือไม่

มีไฟล์มากกว่า 100,000 ไฟล์และแต่ละไฟล์มีข้อมูลอยู่ระหว่าง 20 และมากกว่า 5,000 แถวของข้อมูล โดยปกติ grep จะใช้เพื่อค้นหาหนึ่งอินสแตนซ์ของคำค้นหา

สมมติว่าคำค้นหาคือSEARCHTERMและมันจะอยู่ในแถวเช่นนี้:

NAD+DP+1234567890:92++UNIQUE+NAME+SEARCHTERM++12345+FI'

การค้นหา "SEARCH" หรือ "SEARCHTERM" เร็วกว่านี้หรือไม่ สมมติว่าในกรณีนี้เราไม่สนใจว่าเราพบการแข่งขันในสายอื่น ๆ ที่ไม่เกี่ยวข้องหรือไม่

นี่คือวิธีที่ฉันทำในปัจจุบัน:

grep NAD+DP 123* | grep SEARCHTERM

แต่ฉันพบว่ามันค่อนข้างช้า ปกติจะใช้เวลาประมาณ 3-5 นาทีในการค้นหาข้อมูลแม้ว่าฉันจะรู้ชื่อไฟล์คร่าวๆซึ่ง จำกัด ช่วงไว้ที่ประมาณ 10,000 ไฟล์

ดังนั้นข้อความค้นหาที่ยาวขึ้นหรือสั้นลงจะช่วยได้หรือไม่ เท่าที่ฉันรู้ grep มองหา "บล็อก" ของคำที่มีความยาวแน่นอน?

คำตอบ:


8

วัสดุอ้างอิงบางส่วน:

GNU grep ใช้อัลกอริทึม Boyer-Moore ที่รู้จักกันดีซึ่งจะค้นหาอักษรตัวสุดท้ายของสตริงเป้าหมายและใช้ตารางการค้นหาเพื่อบอกว่ามันสามารถข้ามไปข้างหน้าได้มากแค่ไหนเมื่อเจออักขระที่ไม่ตรงกัน

จากทำไม GNU grep เป็นไปอย่างรวดเร็ว

อัลกอริทึมประมวลผลสตริงที่กำลังค้นหา (รูปแบบ) แต่ไม่ใช่สตริงที่กำลังค้นหา (ข้อความ) [... ] โดยทั่วไปอัลกอริทึมทำงานเร็วขึ้นเมื่อความยาวของรูปแบบเพิ่มขึ้น

จากบอยเยอร์มัวร์วิธีการค้นหาสตริง

สรุป: ใช้สายอีกต่อไป

ตอนนี้มาตรฐานเล็กน้อยเพื่อความสนุกสนาน:

# Initialisation
cd $(mktemp -d) && dd if=/dev/urandom of=random bs=1M count=1000
# Version
grep --v` # grep (GNU grep) 2.9
# Benchmark
(for s in 'short' 'this is not so short and we could even consider this as pretty long'; do for t in {1..10}; do time grep "$s" random; done; done ) 2> result

ผลลัพธ์: 0.952s เป็นค่าเฉลี่ยสำหรับสตริงสั้น ๆ , 0.244s คือค่าเฉลี่ยสำหรับสตริงยาว

หมายเหตุ : ความยาวไม่ใช่เพียงเกณฑ์ที่จะนำมาพิจารณา


0

คุณสามารถลองด้วยตัวคุณเองโดยใช้ SEARCH หรือ SEARCHTERM ลองเปลี่ยนลำดับของคำสั่ง grep สองคำสั่งด้วย อย่างไรก็ตามตัวเลือกที่มีประโยชน์เท่านั้นน่าจะใช้คอร์ CPU หลายตัวสำหรับการค้นหาเพียงครั้งเดียว ดูparallelคำสั่ง


0

ฉันไม่คิดว่าการระบุข้อความค้นหาที่เฉพาะเจาะจงมากขึ้นจะทำให้สังเกตได้เร็วขึ้น

ด้วยไฟล์ที่จะค้นหาจำนวนมากคุณจะต้องจัดทำดัชนีข้อมูลของคุณเพื่อให้การค้นหาเร็วขึ้น

ฉันสามารถแนะนำวิธีไม่กี่:

  • สร้างฐานข้อมูล (PostgreSQL หรือ MySQL) นำเข้าข้อมูลของคุณไปยังฐานข้อมูล - หนึ่งไฟล์ในหนึ่งแถวเพิ่มดัชนี FTS (ค้นหาข้อความแบบเต็ม) สร้างยูทิลิตี้บางอย่างเพื่อค้นหาฐานข้อมูล

  • นำเข้าข้อมูลไปยังฐานข้อมูลอย่างละเอียดยิ่งขึ้นอาจเป็นหนึ่งบรรทัดในหนึ่งแถว (หรืออาจมากกว่าหนึ่งตาราง) สร้างดัชนีเพื่อให้ข้อมูลของคุณสามารถค้นหาได้โดยใช้ index (es) สร้างยูทิลิตี้บางอย่างเพื่อค้นหาฐานข้อมูล

  • เพิ่มไฟล์ของคุณลงในที่gitเก็บบีบอัดโดยgit gcใช้git grepเพื่อค้นหา จากประสบการณ์ของฉันgit grepสามารถเร็วกว่ามาตรฐานได้grepถึง 10 เท่า -10 เท่า


0

ตามเหตุผลแล้วคำศัพท์ที่สั้นกว่าจะต้องใช้เวลา CPU น้อยลงเช่นเดียวกับที่grepทำ

if (filechar[i] == pattern[i]) ...

เวลาน้อยลง ในความเป็นจริงฉันคาดเดาว่าgrepจะเป็น I / O-bound และไม่ใช่ CPU-bound ดังนั้นมันจะไม่สำคัญ


1
น่าแปลกที่ว่านี่เป็นสิ่งที่ผิดเนื่องจาก grep ใช้อัลกอริทึมที่ชาญฉลาดจริงๆโปรดอ้างอิงคำตอบของฉัน
SylvainD

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