ऐसा लगता है कि यह findजांचना होगा कि क्या किसी दिए गए मार्ग को किसी भी तरह से फ़ाइल या निर्देशिका से मेल खाती है ताकि निर्देशिका की सामग्री को पुन: प्राप्त करने के लिए चल सके।
यहाँ कुछ प्रेरणा है और मैंने खुद को समझाने के लिए स्थानीय रूप से जो किया है वह find . -type fवास्तव में धीमा है find .। मैंने GNU में स्रोत कोड अभी तक नहीं खोजा है।
इसलिए मैं अपनी $HOME/Workspaceनिर्देशिका में कुछ फ़ाइलों का समर्थन कर रहा हूं , और उन फ़ाइलों को छोड़कर जो मेरी परियोजनाओं या संस्करण नियंत्रण फ़ाइलों की निर्भरता हैं।
इसलिए मैंने निम्नलिखित कमांड चलाई जो जल्दी से निष्पादित हुई
% find Workspace/ | grep -v '/vendor\|/node_modules/\|Workspace/sources/\|/venv/\|/.git/' > ws-files-and-dirs.txt
findपाइप grepखराब रूप हो सकता है, लेकिन यह एक नकारात्मक रेगेक्स फिल्टर का उपयोग करने का सबसे सीधा तरीका लग रहा था।
निम्न कमांड में केवल खोज के आउटपुट में फाइलें शामिल हैं और इसे अधिक समय तक देखा गया है।
% find Workspace/ -type f | grep -v '/vendor\|/node_modules/\|Workspace/sources/\|/venv/\|/.git/' > ws-files-only.txt
मैंने इन दोनों आदेशों के प्रदर्शन का परीक्षण करने के लिए कुछ कोड लिखे ( dashऔर tcsh, केवल शेल को प्रभावित करने वाले किसी भी प्रभाव को नियंत्रित करने के लिए, हालांकि कोई भी नहीं होना चाहिए)। tcshपरिणाम छूट गए हैं, क्योंकि वे मूलतः एक ही कर रहे हैं।
मुझे मिले परिणामों के लिए लगभग 10% प्रदर्शन का दंड मिला -type f
यहां विभिन्न कमांड के 1000 पुनरावृत्तियों को निष्पादित करने के लिए उठाए गए समय की मात्रा दिखाते हुए कार्यक्रम का आउटपुट है।
% perl tester.pl
/bin/sh -c find Workspace/ >/dev/null
82.986582
/bin/sh -c find Workspace/ | grep -v '/vendor\|/node_modules/\|Workspace/sources/\|/venv/\|/.git/' > /dev/null
90.313318
/bin/sh -c find Workspace/ -type f >/dev/null
102.882118
/bin/sh -c find Workspace/ -type f | grep -v '/vendor\|/node_modules/\|Workspace/sources/\|/venv/\|/.git/' > /dev/null
109.872865
के साथ परीक्षण किया गया
% find --version
find (GNU findutils) 4.4.2
Copyright (C) 2007 Free Software Foundation, Inc.
उबंटू 15.10 पर
यहाँ पेर्ल स्क्रिप्ट का उपयोग मैंने बेंचमार्किंग के लिए किया है
#!/usr/bin/env perl
use strict;
use warnings;
use Time::HiRes qw[gettimeofday tv_interval];
my $max_iterations = 1000;
my $find_everything_no_grep = <<'EOF';
find Workspace/ >/dev/null
EOF
my $find_everything = <<'EOF';
find Workspace/ | grep -v '/vendor\|/node_modules/\|Workspace/sources/\|/venv/\|/.git/' > /dev/null
EOF
my $find_just_file_no_grep = <<'EOF';
find Workspace/ -type f >/dev/null
EOF
my $find_just_file = <<'EOF';
find Workspace/ -type f | grep -v '/vendor\|/node_modules/\|Workspace/sources/\|/venv/\|/.git/' > /dev/null
EOF
my @finds = ($find_everything_no_grep, $find_everything,
$find_just_file_no_grep, $find_just_file);
sub time_command {
my @args = @_;
my $start = [gettimeofday()];
for my $x (1 .. $max_iterations) {
system(@args);
}
return tv_interval($start);
}
for my $shell (["/bin/sh", '-c']) {
for my $command (@finds) {
print "@$shell $command";
printf "%s\n\n", time_command(@$shell, $command);
}
}
-type fइसके बिना और इसके बिना एक ही समय पर चलता है। लेकिन पहली बार लिनक्स कर्नेल ने इसे कैश में लोड किया और बहुत पहले पता चला कि यह धीमा है।
-type fविकल्प की वजह से findकॉल करने के लिए stat()या fstat()या जो कुछ भी क्रम में पता लगाने के लिए यदि फ़ाइल नाम एक फ़ाइल के अनुरूप था, निर्देशिका, एक सिमलिंक, आदि आदि मैं एक किया था straceएक पर find . है और एक find . -type fऔर ट्रेस लगभग समान था, केवल उन write()कॉलों में अंतर करना जिनके पास निर्देशिका नाम थे। इसलिए, मुझे नहीं पता, लेकिन मैं इसका जवाब जानना चाहता हूं।
timeअंतर्निहित कमांड है कि कमांड को निष्पादित करने में कितना समय लगता है, आपको वास्तव में परीक्षण करने के लिए एक कस्टम स्क्रिप्ट लिखने की आवश्यकता नहीं थी।
findजांचना होगा कि क्या किसी दिए गए मार्ग को किसी भी तरह से फ़ाइल या निर्देशिका से मेल खाती है ताकि निर्देशिका की सामग्री को पुन: प्राप्त करने के लिए चल सके। - अगर यह एक निर्देशिका है, तो यह जांचना होगा कि क्या यह एक फ़ाइल है या नहीं। अन्य प्रवेश प्रकार हैं: नामित पाइप, प्रतीकात्मक लिंक, विशेष उपकरणों को ब्लॉक करें, सॉकेट ... इसलिए हो सकता है कि यह पहले से ही यह देखने के लिए चेक किया हो कि क्या यह एक निर्देशिका है, इसका मतलब यह नहीं है कि यह जानता है कि क्या यह एक नियमित फ़ाइल है।