ทำไม GNU ถึงพบว่ารวดเร็วเมื่อเปรียบเทียบกับเครื่องมือค้นหาไฟล์กราฟิก?


47

ฉันพยายามค้นหาไฟล์ที่ไม่มีอยู่ในโฮมไดเรกทอรีของฉันและไดเรกทอรีย่อยทั้งหมด

find ~/ -name "bogus"ให้ข้อมูลแก่ฉันหลังจากนั้นไม่กี่วินาที แต่ตัวจัดการdolphinไฟล์ของ KDEต้องการเวลาเกือบ 3 นาทีในการทำเช่นเดียวกัน สอดคล้องกับที่มีประสบการณ์ก่อนหน้านี้ของฉันกับGNOMEbeagle

การfindจัดการที่จะทำอย่างรวดเร็วเหมือนกันในขณะที่การค้นหากราฟิก (ซึ่งใช้งานง่ายกว่าพารามิเตอร์ commandline) ทากอยู่เบื้องหลัง?


ฉันไม่รู้ว่า "ปลาโลมา" คืออะไร แต่อาจดูในไฟล์ด้วยหรือไม่
Kusalananda

1
มันเป็นตัวจัดการไฟล์กราฟิกจาก KDE: kde.org/applications/system/dolphinมันมีความสามารถในการค้นหาไฟล์ภายใน แต่ฉันไม่ได้เปิดใช้งานตัวเลือกนั้นในระหว่างการทดสอบสั้น ๆ นี้
แดง

9
คุณค้นหาโลมามากกว่าหนึ่งครั้งหรือไม่? อาจเป็น "การจัดทำดัชนี" ครั้งที่ 1 และ "ค้นหา" ก็ช้าเช่นกัน ลอง "ค้นหา" หากไฟล์เก่ากว่าครั้งที่แล้วฐานข้อมูลสำหรับการค้นหาได้รับการจัดทำดัชนี ;-)
Rinzwind

ผมใช้locateบ่อยกว่าfindและเร็วในโฟลเดอร์ใหญ่
phuclv

11
ในขณะที่locateดีมากสำหรับการค้นหาไฟล์นี่เป็นบิต OT เพราะใช้วิธีการที่แตกต่างกันโดยสิ้นเชิง: findและเครื่องมือ GUI เช่นDolphinกำลังสำรวจทรีไฟล์ตามต้องการในขณะที่locateใช้โครงสร้างดัชนีที่สร้างขึ้นก่อนหน้านี้
Michael Schaefers

คำตอบ:


68

เมื่อดูที่ Dolphin with Baloo โดยเฉพาะดูเหมือนว่าจะค้นหาข้อมูลเมตาของทุกไฟล์ในโดเมนการค้นหาแม้ว่าคุณจะทำการค้นหาชื่อไฟล์อย่างง่าย เมื่อผมติดตามfile.soกระบวนการฉันเห็นโทรไปlstat, getxattrและgetxattrอีกครั้งสำหรับทุกไฟล์, และแม้กระทั่งสำหรับ..รายการ การเรียกระบบเหล่านี้จะดึงข้อมูลเมตาเกี่ยวกับไฟล์ที่จัดเก็บในตำแหน่งอื่นจากชื่อไฟล์ (ชื่อไฟล์จะถูกเก็บไว้ในเนื้อหาไดเรกทอรี แต่ข้อมูลเมตาอยู่ในinode ) การสอบถามข้อมูลเมตาของไฟล์หลาย ๆ ครั้งมีราคาถูกเนื่องจากข้อมูลจะอยู่ในดิสก์แคช แต่อาจมีความแตกต่างอย่างมีนัยสำคัญระหว่างการสืบค้นข้อมูลเมตาและไม่ทำการสืบค้นข้อมูลเมตา

findฉลาดกว่านี้มาก พยายามหลีกเลี่ยงการเรียกระบบที่ไม่จำเป็น มันจะไม่โทรgetxattrเพราะมันไม่ได้ค้นหาตามคุณสมบัติเพิ่มเติม เมื่อสำรวจไดเรกทอรีมันอาจต้องเรียกlstatชื่อไฟล์ที่ไม่ตรงกันเนื่องจากอาจเป็นไดเรกทอรีย่อยเพื่อค้นหาแบบเรียกซ้ำ ( lstatเป็นการเรียกระบบที่ส่งคืนข้อมูลเมตาของไฟล์รวมถึงประเภทไฟล์เช่นปกติ / directory / symlink / ... ) อย่างไรก็ตามfindมีการปรับให้เหมาะสม: มันรู้จำนวนไดเรกทอรีย่อยที่ไดเรกทอรีได้จากการนับลิงก์และหยุดการเรียกlstatเมื่อรู้ว่ามันสำรวจผ่านไดเรกทอรีย่อยทั้งหมด โดยเฉพาะในไดเรกทอรีใบไม้ (ไดเรกทอรีที่ไม่มีไดเรกทอรีย่อย)findตรวจสอบชื่อเท่านั้นไม่ใช่ข้อมูลเมตา นอกจากนี้ระบบไฟล์บางระบบยังเก็บสำเนาชนิดของไฟล์ไว้ในรายการไดเรคทอรีเพื่อที่findจะไม่จำเป็นต้องโทรlstatถ้านั่นเป็นข้อมูลที่ต้องการเท่านั้น

หากคุณเรียกใช้findด้วยตัวเลือกที่ต้องตรวจสอบข้อมูลเมตามันจะทำการlstatโทรเพิ่มแต่มันจะไม่ทำการlstatเรียกไฟล์ถ้าไม่ต้องการข้อมูล (ตัวอย่างเช่นเนื่องจากไฟล์ถูกแยกโดยเงื่อนไขก่อนหน้า จับคู่กับชื่อ)

ฉันสงสัยว่าเครื่องมือค้นหา GUI อื่น ๆ ที่สร้างfindวงล้อนั้นฉลาดน้อยกว่ายูทิลิตี้บรรทัดคำสั่งซึ่งได้รับการปรับแต่งมาหลายทศวรรษ อย่างน้อยปลาโลมานั้นฉลาดพอที่จะใช้ฐานข้อมูลการค้นหาหากคุณค้นหา“ ทุกที่” (มีข้อ จำกัด ที่ไม่ชัดเจนใน UI ที่ผลลัพธ์อาจล้าสมัย)


22
GNU พบว่า "ฉลาด" จนพลาดบางไฟล์ในระบบไฟล์บางประเภท ข้อผิดพลาดที่รู้จักกันดีใน GNU พบว่ามันทำให้การสันนิษฐานผิดกฎหมายว่าจำนวนลิงค์ของไดเรกทอรี2 + number of sub-directories.นี้ใช้งานได้กับระบบไฟล์ที่ใช้ข้อผิดพลาดในการออกแบบจากระบบไฟล์ UNIX V7 แต่ไม่ใช่สำหรับระบบไฟล์ทั้งหมดเนื่องจากนี่ไม่ใช่ข้อกำหนด POSIX . หากคุณต้องการได้รับหมายเลขประสิทธิภาพที่เป็นประโยชน์สำหรับการทำ GNU คุณต้องระบุ-noleafเพื่อบอกให้ GNU ทำอย่างถูกต้อง
schily

12
@ schily, GNU findอาจมีข้อผิดพลาดที่นานมาแล้ว แต่ฉันสงสัยว่าคุณจะพบกรณีที่คุณต้องระบุ-noleafด้วยมือในปัจจุบัน AFAICT บน Linux อย่างน้อยgetdents()(และ readdir ()) จะบอกว่าไฟล์ใดเป็นไฟล์ไดเรกทอรีใน UDF, ISO-9660, btrfs ซึ่งไม่มีจริง.หรือมี..รายการและfindทำงานที่นั่น คุณรู้กรณีหนึ่งที่ GNU findแสดงปัญหาหรือไม่
Stéphane Chazelas

4
เพียงใช้ genisoimage ที่เน่าเสียจากเดเบียนเพื่อสร้างระบบไฟล์ Rock Ridge โดยใช้ "กราฟต์จุด" และจำนวนลิงก์ในไดเรกทอรีนั้นเป็นค่าสุ่ม เนื่องจาก Rock Ridge ใช้การนับลิงก์และ. / .. , GNU find จะไม่ค้นหาไฟล์ทั้งหมดในระบบไฟล์ดังกล่าว
Schily

4
@ StéphaneChazelas: ครั้งสุดท้ายที่ฉันตรวจสอบ (สำหรับวิทยานิพนธ์ปริญญาโทของฉัน) ข้อผิดพลาดได้รับการแก้ไขโดยยืนยันว่า 2 หมายถึงใบไม้ที่รู้จักกันดีกว่า <= 2 ระบบแฟ้มที่ไม่ได้ใช้ 2+ ตัวนับทั้งหมดกลับ 1 สำหรับการเชื่อมโยงไดเรกทอรี ทุกอย่างดี ตอนนี้ถ้าวันหนึ่งมีคนสร้างระบบไฟล์ที่ไม่ได้ลิงก์ไปยังไดเรกทอรีที่ไม่มีคุณสมบัตินี้ใครบางคนกำลังจะมีวันที่แย่
Joshua

15
@ schily ฉันไม่สามารถรับการนับลิงก์แบบสุ่มด้วย graft-points และ RR ด้วย genisoimage 1.1.11 บน Debian และแม้ว่าฉันจะแก้ไขภาพ iso แบบไบนารี่เพื่อเปลี่ยนการนับลิงก์เป็นค่าสุ่มฉันก็ยังไม่เห็นอะไรเลย ปัญหากับ findGNU และไม่ว่าในกรณีใดก็ตามstrace -vแสดงว่าgetdents()ส่งคืน d_type = DT_DIR สำหรับไดเรกทอรีอย่างถูกต้องดังนั้น GNU find จึงไม่จำเป็นต้องใช้เคล็ดลับในการนับลิงก์
Stéphane Chazelas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.