"স্পর্শ" এর চেয়ে "প্রতিধ্বনি" এত দ্রুত কেন?


116

আমি আমার ডিরেক্টরিতে (পুনরাবৃত্তভাবে) সমস্ত এক্সএমএল ফাইলের বর্তমান সময়ে টাইমস্ট্যাম্পটি আপডেট করার চেষ্টা করছি। আমি ম্যাক ওএসএক্স 10.8.5 ব্যবহার করছি।

প্রায় 300,000 ফাইলগুলিতে, নিম্নলিখিত echoকমান্ডটি 10 সেকেন্ড সময় নেয় :

for file in `find . -name "*.xml"`; do echo >> $file; done

তবে, নিম্নলিখিত touchকমান্ডটি 10 মিনিট সময় নেয় ! :

for file in `find . -name "*.xml"`; do touch $file; done

এখানে স্পর্শের চেয়ে প্রতিধ্বনি এত দ্রুত কেন?


20
শুধু একটি পক্ষ মন্তব্য: আপনি কি জানেন যে এই দুটি কমান্ড সমান নয়, তাই না? কমপক্ষে ইউনিক্স / লিনাক্সের জন্য, এর জন্য echo >> $fileএকটি নতুন লাইন যুক্ত হবে $fileএবং এটি এটিকে সংশোধন করবে। আমি ধরে নিয়েছি এটি ওএস / এক্স এর সমান হবে। আপনি যদি এটি না চান তবে ব্যবহার করুন echo -n >> $file
দুবু

2
touch `find . -name "*.xml"` উপরোক্ত উভয়ের চেয়েও দ্রুত হবে না ?
এলমো

4
বা ন্যায়সঙ্গত বিবেচনা করুন>>$file
অঙ্কিত

8
সুস্পষ্ট প্রশ্নের উত্তর নয়, তবে কেন এতবার অনুরোধ করা হচ্ছে touch? অনেক কম বার find . -name '*.xml' -print0 | xargs -0 touchআহ্বান জানায় touch(সম্ভবত কেবল একবার)। লিনাক্সে কাজ করে, ওএস এক্সে কাজ করা উচিত
মাইক রেনফ্রো

3
@ ইলমো যুক্তি তালিকা খুব দীর্ঘ (সহজেই, 300.000 ফাইল সহ ...)
রুমো

উত্তর:


161

ব্যাশে, touchএটি একটি বাহ্যিক বাইনারি, তবে echoএটি শেল অন্তর্নির্মিত :

$ type echo
echo is a shell builtin
$ type touch
touch is /usr/bin/touch

যেহেতু touchএকটি বাহ্যিক বাইনারি, এবং আপনি touchপ্রতি ফাইল প্রতি একবার অনুরোধ করছেন, শেলটি অবশ্যই 300,000 দৃষ্টান্ত তৈরি করতে হবে touch, এতে দীর্ঘ সময় লাগে।

echoতবে, এটি একটি শেল বিল্টিন এবং শেল বিল্টিনগুলি কার্যকর করার জন্য একেবারে কাঁটাচামচ লাগবে না। পরিবর্তে, বর্তমান শেলটি সমস্ত অপারেশন করে এবং কোনও বাহ্যিক প্রক্রিয়া তৈরি হয় না; এটি এত দ্রুত হওয়ার কারণ is

শেলের ক্রিয়াকলাপের এখানে দুটি প্রোফাইল। আপনি দেখতে পাচ্ছেন যে নতুন প্রসেসগুলি ক্লোনিং করার সময় প্রচুর সময় ব্যয় হয় touch/bin/echoশেল বিল্টিনের পরিবর্তে ব্যবহার করলে আরও অনেক তুলনামূলক ফলাফল দেখা উচিত।


স্পর্শ ব্যবহার

$ strace -c -- bash -c 'for file in a{1..10000}; do touch "$file"; done'
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 56.20    0.030925           2     20000     10000 wait4
 38.12    0.020972           2     10000           clone
  4.67    0.002569           0     80006           rt_sigprocmask
  0.71    0.000388           0     20008           rt_sigaction
  0.27    0.000150           0     10000           rt_sigreturn
[...]

প্রতিধ্বনি ব্যবহার

$ strace -c -- bash -c 'for file in b{1..10000}; do echo >> "$file"; done'
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 34.32    0.000685           0     50000           fcntl
 22.14    0.000442           0     10000           write
 19.59    0.000391           0     10011           open
 14.58    0.000291           0     20000           dup2
  8.37    0.000167           0     20013           close
[...]

1
আপনি কি ওএস এক্স-এ স্ট্রেস সংকলন করেছেন বা অন্য কোনও ওএসে পরীক্ষা চালিয়েছেন?
bmike

1
@ বিমাইক আমার পরীক্ষাটি লিনাক্সে রয়েছে তবে নীতিটি অভিন্ন।
ক্রিস ডাউন

আমি সম্পূর্ণরূপে সম্মত - / বিন / প্রতিধ্বনি / বিন / স্পর্শের মতো ধীর তাই মূল যুক্তিতে আমার মন্তব্য দেখুন যাতে যুক্তিটি শোনানো। আমি কেবল স্ট্রেসের সময় পুনরুত্পাদন করতে চেয়েছিলাম এবং dtruss / dtrace ব্যবহার করে ব্যর্থ হয়েছি এবং ওএস এক্স-তে প্রত্যাশা অনুযায়ী বাশ-সি সিনট্যাক্স কাজ করে না।
বমিক করুন

71

যেমনটি অন্যেরা উত্তর দিয়েছেন, শেলটিতে অন্তর্নির্মিত যা কমান্ডটি সাধারণত (যদিও প্রয়োজন হয় না) echoতার চেয়ে touchতত দ্রুত হবে echo। এটি ব্যবহার করা আপনার সাথে প্রতিটি ফাইলের জন্য একটি নতুন প্রক্রিয়া শুরু করার সাথে যুক্ত কার্নেল ওভারহেডের সাথে সম্পর্কিত touch

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

find . -name "*.xml" -exec touch {} +

আর্গুমেন্ট হিসাবে প্রতিটি ফাইলের সাথে সম্ভব হলে কমান্ডটি একবার ব্যবহার করে +(বিপরীতে \;) ব্যবহার করা হয় find ... -exec। যদি আর্গুমেন্ট তালিকাটি দীর্ঘ হয় (যেমন 300,000 ফাইলের ক্ষেত্রে হয়) একাধিক রান একটি আর্গুমেন্ট তালিকার সাহায্যে তৈরি করা হবে যার সীমাটির সীমা প্রায় ( ARG_MAXবেশিরভাগ সিস্টেমে) রয়েছে।

এই পদ্ধতির আরেকটি সুবিধা হ'ল এটি সমস্ত সাদা স্থানের অক্ষরযুক্ত ফাইলের নামগুলির সাথে দৃ rob়তার সাথে আচরণ করে যা মূল লুপের ক্ষেত্রে নয়।


17
+1+যুক্তি খুঁজে বের করার জন্য । আমি মনে করি অনেক লোক এ সম্পর্কে অবগত নয় (আমি ছিলাম না)।
অঙ্কুরিত

7
না এর সব সংস্করণ findআছে +যুক্তি। আপনি পাইপ দিয়ে অনুরূপ প্রভাব পেতে পারেন xargs
বার্মার

5
@ বারমার, +অংশটি পসিক্স দ্বারা প্রয়োজনীয়, সুতরাং বহনযোগ্য হতে হবে। -print0নয়।
গ্রিম

1
আমি এখনও মাঝে মধ্যে বাস্তবায়নগুলিতে চালিত করি যা এটি নেই। YMMV।
বর্মার

1
@ ক্রিসডাউন, আমি যে কিছু আবিষ্কার করেছি তা হ'ল ব্যাসিবক্সের findবিকল্প রয়েছে তবে এটি কেবল ;পৃষ্ঠের নীচের মতো আচরণ করে ।
গ্রিম

29

echoএকটি শেল অন্তর্নির্মিত। অন্যদিকে, touchএকটি বাহ্যিক বাইনারি।

$ type echo
echo is a shell builtin
$ type touch
touch is hashed (/usr/bin/touch)

প্রোগ্রাম লোড করার ক্ষেত্রে কোনও ওভারহেড জড়িত না থাকায় শেল বিল্টিনগুলি আরও দ্রুত হয়, অর্থাত্ কোনও fork/ execজড়িত নেই। যেমন, একটি বিল্টিন বনাম বাহ্যিক কমান্ড প্রচুর পরিমাণে কার্যকর করার সময় আপনি একটি গুরুত্বপূর্ণ সময়ের পার্থক্যটি পর্যবেক্ষণ করতে পারেন।

এই কারণেই ইউটিলিটিগুলি timeশেল বিল্টিন হিসাবে উপলব্ধ।

আপনি শেল বিল্টিনগুলির সম্পূর্ণ তালিকাটি এইভাবে বলতে পারেন:

enable -p

উপরে উল্লিখিত হিসাবে, ইউটিলিটি বিল্টিনের বিপরীতে হিসাবে ব্যবহার করে ফলাফলের উল্লেখযোগ্য কার্যকারিতা অবনতি ঘটে। বিল্টিন echo এবং ইউটিলিটিটি ব্যবহার করে 000 9000 ফাইল তৈরি করতে যে সময়টির পরিসংখ্যান রয়েছে তা নীচে echo:

# Using builtin
$ time bash -c 'for i in {1000..9999}; do echo > $i; done'

real    0m0.283s
user    0m0.100s
sys 0m0.184s

# Using utility /bin/echo
$ time bash -c 'for i in {1000..9999}; do /bin/echo > $i; done'

real    0m8.683s
user    0m0.360s
sys 0m1.428s

এবং আমি মনে করি echoবেশিরভাগ সিস্টেমে বাইনারি রয়েছে (আমার জন্য এটি /bin/echo), তাই আপনি বিল্ট-
ইনগুলির

@ মিশেলমরোজেক বিল্টিন এবং বাইনারিগুলির জন্য টাইমিং টেস্ট যুক্ত করেছে।
ডেভনুল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.