Tại sao GNU tìm thấy quá nhanh so với các tiện ích tìm kiếm tệp đồ họa?


47

Tôi đang cố gắng tìm một tệp không tồn tại trong thư mục nhà của tôi và tất cả các thư mục con.

find ~/ -name "bogus"cung cấp cho tôi thông tin đó sau vài giây, nhưng trình quản lý tệp của KDEdolphin cần gần 3 phút để thực hiện tương tự. Điều này tương ứng với kinh nghiệm trước đây của tôi với Gnomebeagle .

Làm thế nào để findquản lý để làm điều tương tự rất nhanh trong khi tìm kiếm đồ họa (sử dụng trực quan hơn so với tham số dòng lệnh) nằm phía sau?


Tôi không biết "Cá heo" là gì, nhưng nó cũng có thể nhìn vào bên trong các tập tin?
Kusalananda

1
Đó là trình quản lý tệp đồ họa từ KDE: kde.org/appluggest/system/dolphin Nó có khả năng tìm kiếm bên trong các tệp, nhưng tôi đã không bật tùy chọn đó trong bài kiểm tra ngắn này.
Red

9
Bạn đã tìm kiếm nhiều hơn một lần trong cá heo? Nó có thể là "lập chỉ mục" lần đầu tiên. Và "tìm" cũng chậm. Hãy thử "định vị" nếu tệp cũ hơn lần trước cơ sở dữ liệu để xác định vị trí được lập chỉ mục ;-)
Rinzwind

Tôi sử dụng locatethường xuyên hơn findvà nó nhanh hơn trong một thư mục lớn
phuclv

11
Mặc dù locatethực sự tuyệt vời để tìm tệp, đây là một chút OT, vì nó sử dụng một cách tiếp cận hoàn toàn khác: findvà các công cụ GUI như Dolphinđang duyệt qua cây tệp theo yêu cầu, trong khi locateđang sử dụng cấu trúc chỉ mục được tạo trước đó.
Michael Schaefers

Câu trả lời:


68

Nhìn vào cá heo với Baloo một cách cụ thể, nó dường như tìm kiếm siêu dữ liệu của mọi tệp trong miền tìm kiếm của nó, ngay cả khi bạn đang thực hiện tìm kiếm tên tệp đơn giản. Khi tôi theo dõi các file.soquá trình, tôi thấy cuộc gọi đến lstat, getxattrgetxattrmột lần nữa cho mỗi tập tin, và ngay cả đối với ..các mục. Những cuộc gọi hệ thống lấy siêu dữ liệu về các tập tin được lưu trữ trong một vị trí khác nhau từ tên tập tin (tên tập tin được lưu trữ trong nội dung thư mục, nhưng các siêu dữ liệu đang trong inode ). Truy vấn siêu dữ liệu của một tệp nhiều lần là rẻ vì dữ liệu sẽ nằm trong bộ đệm của đĩa, nhưng có thể có một sự khác biệt đáng kể giữa truy vấn siêu dữ liệu và không truy vấn siêu dữ liệu.

findthông minh hơn nhiều. Nó cố gắng tránh các cuộc gọi hệ thống không cần thiết. Nó sẽ không gọi getxattrvì nó không tìm kiếm dựa trên các thuộc tính mở rộng. Khi đi ngang qua một thư mục, nó có thể cần phải gọi lstatcác tên tệp không khớp bởi vì đó có thể là thư mục con để tìm kiếm đệ quy ( lstatlà cuộc gọi hệ thống trả về siêu dữ liệu tệp bao gồm loại tệp như thông thường / thư mục / symlink / Nott). Tuy nhiên findcó một tối ưu hóa: nó biết có bao nhiêu thư mục con mà thư mục có từ số lượng liên kết của nó và nó dừng cuộc gọi lstatmột khi nó biết rằng nó đi qua tất cả các thư mục con. Cụ thể, trong một thư mục lá (một thư mục không có thư mục con),findchỉ kiểm tra tên, không phải siêu dữ liệu. Hơn nữa, một số hệ thống tệp giữ một bản sao của loại tệp trong mục nhập thư mục để findthậm chí không cần gọi lstatnếu đó là thông tin duy nhất mà nó cần.

Nếu bạn chạy findvới các tùy chọn yêu cầu kiểm tra siêu dữ liệu, nó sẽ thực hiện nhiều lstatcuộc gọi hơn , nhưng nó vẫn không thực hiện lstatcuộc gọi trên một tệp nếu không cần thông tin (ví dụ: vì tệp bị loại trừ bởi một điều kiện trước đó khớp với tên).

Tôi nghi ngờ rằng các công cụ tìm kiếm GUI khác phát minh lại findbánh xe cũng kém thông minh hơn tiện ích dòng lệnh đã trải qua nhiều thập kỷ tối ưu hóa. Ít nhất, cá heo đủ thông minh để sử dụng cơ sở dữ liệu định vị nếu bạn tìm kiếm trên khắp mọi nơi, (với giới hạn không rõ ràng trong giao diện người dùng rằng kết quả có thể bị lỗi thời).


22
GNU find rất "thông minh" đến nỗi nó bỏ lỡ một số tệp trên một số loại hệ thống tệp. Lỗi nổi tiếng trong GNU find là nó đưa ra giả định bất hợp pháp rằng số lượng liên kết của một thư mục là 2 + number of sub-directories.Điều này hoạt động đối với các hệ thống tệp thực hiện lỗi thiết kế từ hệ thống tệp UNIX V7, nhưng không phải cho tất cả các hệ thống tệp, vì đây không phải là yêu cầu POSIX . Nếu bạn muốn có được một số hiệu suất hữu ích cho GNU make, bạn cần chỉ định -noleaftheo thứ tự để yêu cầu GNU make hành xử chính xác.
schily

12
@schily, GNU findcó thể đã có lỗi đó từ lâu, nhưng tôi nghi ngờ bạn sẽ tìm thấy một trường hợp mà bạn cần chỉ định -noleafbằng tay ngày nay. AFAICT, trên Linux ít nhất getdents()(và readdir ()) cho biết tệp nào là tệp thư mục trên UDF, ISO-9660, btrfs không có thực .hoặc ..mục và findhoạt động OK ở đó. Bạn có biết một trường hợp GNU findthể hiện vấn đề này không?
Stéphane Chazelas

4
Chỉ cần sử dụng genisoimage thối này từ debian để tạo một hệ thống tập tin Rock Ridge bằng cách sử dụng "điểm ghép" và số lượng liên kết trong một thư mục là một giá trị ngẫu nhiên. Do Rock Ridge thực hiện số lượng liên kết và. / .., GNU find thường sẽ không tìm thấy tất cả các tệp trên một hệ thống tệp như vậy.
schily

4
@ StéphaneChazelas: Lần trước tôi đã kiểm tra (đối với luận án thạc sĩ của tôi), lỗi đã được sửa bằng cách xác nhận chính xác 2 lá có nghĩa là thay vì <= 2. Các hệ thống tệp không thực hiện bộ đếm 2+ trả về 1 cho số liên kết thư mục mọi thứ đều tốt Bây giờ nếu một ngày nào đó ai đó tạo ra một hệ thống tập tin có liên kết cứng đến các thư mục không có thuộc tính này, thì ai đó sẽ có một ngày tồi tệ.
Joshua

15
@schily, tôi không thể có được số lượng liên kết ngẫu nhiên với điểm ghép và RR với genisoimage 1.1.11 trên Debian và ngay cả khi tôi chỉnh sửa nhị phân hình ảnh iso để thay đổi số lượng liên kết thành giá trị ngẫu nhiên, tôi vẫn không thấy bất kỳ vấn đề với GNU find. Và trong mọi trường hợp, strace -vcho thấy getdents()trả về chính xác d_type = DT_DIR cho các thư mục, vì vậy GNU find không phải sử dụng thủ thuật đếm liên kết.
Stéphane Chazelas
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.