কেন পাই ` টাইপ f` `সন্ধান। than এর চেয়ে বেশি সময় নেয়?


15

দেখে মনে হচ্ছে findযে ডিরেক্টরিগুলির বিষয়বস্তুগুলিকে পুনরাবৃত্তভাবে চলার জন্য প্রদত্ত পাথটি কোনও ফাইল বা ডিরেক্টরিতে সামঞ্জস্য করে কিনা।

এখানে কিছুটা অনুপ্রেরণা এবং আমি স্থানীয়ভাবে যা করেছি তা বোঝাতে যে find . -type fসত্যিকারের চেয়ে ধীর find .। আমি এখনও জিএনইউ সোর্স কোডটি খুঁজে পাইনি।

সুতরাং আমি আমার $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 পুনরাবৃত্তিগুলি কার্যকর করতে সময় পরিমাণ দেখাচ্ছে showing

% 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);
    }
}

2
দেখে মনে হচ্ছে findযে ডিরেক্টরিগুলির বিষয়বস্তুগুলিকে পুনরাবৃত্তভাবে চলার জন্য প্রদত্ত পাথটি কোনও ফাইল বা ডিরেক্টরিতে সামঞ্জস্য করে কিনা। - এটি ডিরেক্টরি কিনা এটি যাচাই করতে হবে, এটি কোনও ফাইল কিনা তা যাচাই করতে হবে না। অন্যান্য প্রবেশের ধরণ রয়েছে: নামযুক্ত পাইপ, প্রতীকী লিঙ্কগুলি, বিশেষ ডিভাইসগুলি, সকেটগুলি ব্লক করুন ... সুতরাং এটি ডিরেক্টরিটি কিনা তা ইতিমধ্যে চেকটি করতে পেরেছে, এর অর্থ এই নয় যে এটি কোনও নিয়মিত ফাইল কিনা তা জানে না।
রিয়েলস্কেপটিক

ব্যস্তবক্স অনুসন্ধান, 4,3 কে ডায়ার দিয়ে এলোমেলো ডিরেক্টরিতে প্রয়োগ করা হয়েছে এবং এটির সাথে -type fএবং ছাড়াও 2,8 কে ফাইলগুলি একই সময়ে চালিত হয় । তবে প্রথমবারে লিনাক্স কার্নেল এটিকে ক্যাশে লোড করেছিল এবং খুব প্রথম ধীরে ধীরে এটি খুঁজে পাওয়া যায়।

1
আমার প্রথম অনুমানটি ছিল যে ফাইলটির নাম কোনও ফাইল, ডিরেক্টরি, একটি সিমলিংক ইত্যাদির সাথে সম্পর্কিত কিনা তা সন্ধান করার জন্য কলটি বা যা কিছু যা -type fঘটেছিল তা আবিষ্কার করতে পেরেছি এবং আমি এটি একটি এবং একটিতে করেছি এবং ট্রেসটি প্রায় অভিন্ন ছিল, কেবলমাত্র সেই কলগুলিতে পৃথক হয় যেগুলির মধ্যে ডিরেক্টরি নাম ছিল। সুতরাং, আমি জানি না, তবে আমি উত্তরটি জানতে চাই। findstat()fstat()stracefind . find . -type fwrite()
ব্রুস এডিগার

1
সত্যিই আপনার প্রশ্নের উত্তর নয়, তবে একটি timeবিল্টিন কমান্ড রয়েছে যে কোনও কমান্ড কার্যকর করতে কতক্ষণ সময় নেয় তা দেখার জন্য আপনাকে সত্যিকার অর্থে পরীক্ষা করার জন্য একটি কাস্টম স্ক্রিপ্ট লেখার দরকার নেই।
এলরনড

উত্তর:


16

জিএনইউ ফাইন্ডের একটি অপ্টিমাইজেশন রয়েছে যা প্রয়োগ করা যেতে পারে find .তবে তা নয় find . -type f: এটি যদি জানেন যে কোনও ডিরেক্টরিতে থাকা অবশিষ্ট এন্ট্রিগুলির কোনওটিই ডিরেক্টরি নয়, তবে এটির একটি না হলে ফাইলের ধরন ( statসিস্টেম কল সহ) নির্ধারণ করা বিরক্ত করে না অনুসন্ধানের মানদণ্ডের এটির প্রয়োজন। কলিংটি statপরিমাপযোগ্য সময় নিতে পারে যেহেতু তথ্যটি সাধারণত ইনোডে থাকে, ডিস্কের অন্তর্ভুক্ত ডিরেক্টরিটি না করে ডিস্কের পৃথক স্থানে।

এটা কিভাবে জানবে? কারণ কোনও ডিরেক্টরিতে লিঙ্ক গণনাটি ইঙ্গিত করে যে এর কতগুলি উপ-ডিরেক্টরি রয়েছে। টিপিক্যাল ইউনিক্স ফাইল সিস্টেমে ডিরেক্টরিগুলির লিঙ্ক গণনাটি 2 টি অতিরিক্ত সংখ্যার ডিরেক্টরি: তার প্যারেন্টে ডিরেক্টরিতে প্রবেশের জন্য একটি, .প্রবেশের জন্য একটি ..এবং প্রতিটি উপ-ডিরেক্টরিতে প্রবেশের জন্য একটি ।

-noleafবিকল্প বলে findএই অপ্টিমাইজেশান প্রয়োগ না। যদি findএমন কোনও ফাইল সিস্টেমে ডাকা হয় যেখানে ডিরেক্টরি লিঙ্ক গণনাগুলি ইউনিক্স কনভেনশন অনুসরণ না করে তবে এটি কার্যকর।


এটি কি এখনও প্রাসঙ্গিক? উত্সটির দিকে findতাকানো, এটি কেবল আজকাল কল fts_open()এবং fts_read()কলগুলি ব্যবহার করে ।
রিয়েলস্কেপটিক

@ রিয়েলসকেপটিক কি সাম্প্রতিক সংস্করণগুলিতে এটি পরিবর্তন হয়েছে? আমি উত্সটি যাচাই করি নি, তবে পরীক্ষামূলকভাবে, ডিবান স্ট্যাবিলিয়ায় সংস্করণ ৪.৪.২ statকল ডাইরেক্টরি লিঙ্ক গণনার কারণে কলগুলির প্রয়োজন হয় না, এবং -noleafবিকল্পটি ম্যানুয়ালটিতে নথিভুক্ত করা হয়।
গিলস 'অসন্তুষ্ট হওয়া বন্ধ করুন'

এটা তোলে সেরা অনুকূল রূপ দেয় statএমনকি fts...সংস্করণ - এটি যে জন্য যথাযথ পতাকা পাসের fts_openকল। তবে আমি যে বিষয়ে এখনও নিশ্চিত নই তা হ'ল লিঙ্কের সংখ্যা সহ চেক। পরিবর্তিত ফিটিস রেকর্ডটিতে "ডিরেক্টরি" ফ্ল্যাগগুলির মধ্যে একটি রয়েছে কিনা তা এটি পরীক্ষা করে। এটি হতে পারে যে fts_readনিজেই এই পতাকাটি সেট করার জন্য লিঙ্কগুলি পরীক্ষা করে, তবে findতা করে না। আপনার সংস্করণ ftsকল করার মাধ্যমে নির্ভর করে কিনা তা আপনি দেখতে পারেন find --version
রিয়েলস্কেপটিক

@ গিলিস, findকোনও ডিরেক্টরিতে সমস্ত প্রবেশিকাও ডিরেক্টরিতে থাকা এবং সেই তথ্যটি ব্যবহার করার পরে তাত্ত্বিকভাবে তা নির্ধারণ করতে সক্ষম হবেন?
গ্রেগরি নিসবেট

@ গ্রেগরিনিসবেট তত্ত্বের ক্ষেত্রে হ্যাঁ, তবে উত্স কোড (আমি এখন যাচাই করেছি) তা করে না, সম্ভবত এটি খুব বিরল ঘটনা বলে।
গিলস 'অসন্তুষ্ট হওয়া বন্ধ করুন'
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.