Điều gì là tốn kém, là thực hiện các cuộc gọi hệ thống trên các tệp (đối với hệ thống tự gọi và cho I / O).
Những thứ như -type, -mtimeyêu cầu một lstat(2)cuộc gọi hệ thống trên tập tin. -name, -path, -regexKhông (mặc dù dĩ nhiên nó sẽ có các cuộc gọi hệ thống thực hiện để các thư mục chứa chúng để đọc nội dung của họ).
Thông thường, findkhông một lstat()anyway (vì nó cần phải biết liệu một tập tin là một thư mục hoặc không đi vào trong nó, trừ khi thông tin được cung cấp trong readdir()), nhưng có những trường hợp nó có thể làm mà không có nó. Chẳng hạn, nếu số lượng liên kết của một thư mục ít hơn 3, thì trong một số hệ thống tập tin, findbiết rằng nó không có các thư mục con và một số findtriển khai sẽ tối ưu hóa bằng cách không thực hiện lstattrong đó.
-xtypesẽ gây ra một stat(2),-printf ... , -lscó thể gây ra stat(), lstat(), readlink(), -lnamemột lstat()và readlink().
Đó là lý do tại sao bạn có thể muốn đặt -name/ -path/ -regex... đầu tiên. Nếu họ có thể loại trừ một tập tin, họ có thể tránh một hoặc nhiều tòa nhà.
Bây giờ, một cái -regexcó thể đắt hơn một -name, nhưng tôi không chắc bạn sẽ nhận được nhiều bằng cách hoán đổi chúng.
Cũng lưu ý rằng một số find triển khai như GNU findthực hiện sắp xếp lại các kiểm tra theo mặc định khi có thể. Xem:
info find 'Optimisation Options'
trên hệ thống GNU ( có trên gnu.org cho phiên bản GNU mới nhất findutils).
Thông thường, nếu bạn đã thực hiện các thử nghiệm của mình trên một hệ thống GNU, cả hai lệnh sẽ làm điều tương tự vì dù sao findcũng sẽ di chuyển -namevề phía trước.
Vì vậy, để -type d -name ...so -name ... -type dsánh để tạo sự khác biệt, bạn cần một findtriển khai không tối ưu hóa bằng cách sắp xếp lại các vị từ đó và một trong đó tối ưu hóa bằng cách không thực hiện lstat()trên mỗi tệp.
Trường hợp sẽ có một sự khác biệt (rất lớn) bất kể việc triển khai là ở đâu:
find . -name 'x*' -exec test -d {} \; -print
vs
find . -exec test -d {} \; -name 'x*' -print
find không thể sắp xếp lại -exec như vậy có thể giới thiệu các khác biệt về chức năng ( findkhông thể biết liệu lệnh được thực thi chỉ để thử nghiệm hay thực hiện việc gì khác).
Và dĩ nhiên -exec ... {} \; là một số đơn đặt hàng có giá trị lớn hơn bất kỳ vị từ nào khác vì nó có nghĩa là thực hiện một quy trình và thực thi một lệnh trong đó (bản thân nó đang chạy nhiều lệnh gọi hệ thống) và chờ đợi nó và mã thoát của nó.
$ time find /usr/lib -exec test -d {} \; -name z\* -print > /dev/null
1.03s user 12.52s system 21% cpu 1:03.43 total
$ time find /usr/lib -name z\* -exec test -d {} \; -print > /dev/null
0.09s user 0.14s system 62% cpu 0.367 total
(cuộc gọi đầu tiên test cho mọi tệp trong /usr/lib(56685), cái thứ hai chỉ trên những tệp có tên bắt đầu bằng z(147)).
Lưu ý rằng -exec test -d {} \;không giống như -type d. Đó là tương đương di động của cụ thể GNU -xtype d.
-name ..và-type dsẽ có vấn đề. Thử nghiệm của bạn dường như chỉ ra rằng nó không.