Đ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
, -mtime
yêu cầu một lstat(2)
cuộc gọi hệ thống trên tập tin. -name
, -path
, -regex
Khô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, find
khô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, find
biết rằng nó không có các thư mục con và một số find
triển khai sẽ tối ưu hóa bằng cách không thực hiện lstat
trong đó.
-xtype
sẽ gây ra một stat(2)
,-printf ...
, -ls
có thể gây ra stat()
, lstat()
, readlink()
, -lname
mộ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 -regex
có 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 find
thự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 find
cũng sẽ di chuyển -name
về phía trước.
Vì vậy, để -type d -name ...
so -name ... -type d
sánh để tạo sự khác biệt, bạn cần một find
triể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 ( find
khô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 d
sẽ có vấn đề. Thử nghiệm của bạn dường như chỉ ra rằng nó không.