বাশ 5.0 এ সমাধান করা হয়েছে
পটভূমি
পটভূমির জন্য (এবং বোঝার জন্য (এবং এই প্রশ্নটি নিম্নোক্তদের এড়াতে চাইছে বলে মনে হচ্ছে)) আমি এই পথে যে পথটি পেয়েছি তা ব্যাখ্যা করব (ভাল, আমি দু'মাস পরে সবচেয়ে ভাল বলতে পারি)।
ধরুন আপনি ইউনিকোড অক্ষরের তালিকার জন্য কয়েকটি শেল পরীক্ষা করছেন:
printf "$(printf '\\U%x ' {33..200})"
এবং সেখানে আরও প্রায় 1 মিলিয়ন ইউনিকোড অক্ষর রয়েছে, 20.000 এর মধ্যে পরীক্ষা হচ্ছে এটি খুব বেশি বলে মনে হচ্ছে না।
এছাড়াও ধরে নিন যে আপনি অবস্থানগুলি আর্গুমেন্ট হিসাবে সেট করেছেন:
set -- $(printf "$(printf '\\U%x ' {33..20000})")
প্রতিটি ফাংশনে চরিত্রগুলিকে বিভিন্ন উপায়ে প্রক্রিয়া করার উদ্দেশ্যে সুতরাং ফাংশনগুলির ফর্ম test1 "$@"
বা অনুরূপ হওয়া উচিত । এখন আমি বুঝতে পারি যে এটি কীভাবে খারাপ ধারণা in
এখন ধরে নিন, কোনটি ভাল তা খুঁজে বের করার জন্য প্রতিটি সমাধানের সময়ের (একটি এন = 1000) প্রয়োজন রয়েছে, এইরকম পরিস্থিতিতে আপনি এর মতো কাঠামোর সাথে শেষ করবেন:
#!/bin/bash --
TIMEFORMAT='real: %R' # '%R %U %S'
set -- $(printf "$(printf '\\U%x ' {33..20000})")
n=1000
test1(){ echo "$1"; } >/dev/null
test2(){ echo "$#"; } >/dev/null
test3(){ :; }
main1(){ time for i in $(seq $n); do test1 "$@"; done
time for i in $(seq $n); do test2 "$@"; done
time for i in $(seq $n); do test3 "$@"; done
}
main1 "$@"
test#
এখানে উপস্থাপন করার জন্য ফাংশনগুলি খুব সাধারণভাবে তৈরি করা হয়।
আসলগুলি আস্তে আস্তে ছাঁটাই হয়েছিল যেখানে খুঁজে পেতে বিশাল দেরি হয়েছিল।
উপরের স্ক্রিপ্টটি কাজ করে, আপনি এটি চালাতে পারেন এবং খুব সামান্য কিছু সময় ব্যয় করতে পারেন।
বিলম্বটি ঠিক কোথায় ছিল তা সন্ধানের সরলকরণের প্রক্রিয়াতে (এবং প্রতিটি পরীক্ষার ক্রিয়াকলাপকে প্রায় কোনও ক্ষেত্রেই হ্রাস করা চূড়ান্ত নয় অনেক পরীক্ষার পরে) আমি সিদ্ধান্ত নিয়েছি প্রতিটি পরীক্ষার কার্যক্রমে যুক্তিগুলি পাস করার সময়টি কতটা উন্নত হয়েছে তা সরাতে কেবলমাত্র 6 এর একটি ফ্যাক্টর, বেশি নয়।
নিজেকে চেষ্টা করার জন্য, সমস্ত "$@"
ফাংশনটি মুছে ফেলুন main1
(বা একটি অনুলিপি তৈরি করুন) এবং আবার (বা উভয় main1
এবং অনুলিপি main2
(সাথে main2 "$@"
)) তুলনা করুন। এটি মূল পোস্টে (ওপি) নীচে নীচে বেসিক কাঠামো।
তবে আমি ভাবলাম: শেলটি "কিছুই করতে" কেন এত দিন নিচ্ছে? হ্যাঁ, শুধুমাত্র "কয়েক সেকেন্ড", তবে এখনও, কেন ?.
এটি আমাকে অন্যান্য শেলগুলিতে পরীক্ষা করার জন্য এটি আবিষ্কার করেছিল যে কেবল বাশের কাছেই এই সমস্যা ছিল। (উপরের মত একই স্ক্রিপ্ট)
চেষ্টা করুন ksh ./script
।
এটি এই বিবরণীর দিকে পরিচালিত করে: test#
কোনও যুক্তি ছাড়াই একটি ফাংশন ( ) কল করা পিতা-মাতার মধ্যে যুক্তি দ্বারা বিলম্বিত হয় ( main#
)। এটি নীচের নীচে মূল পোস্ট (ওপি) এর পরে নিম্নলিখিত বর্ণনাকারী ছিল।
আসল পোস্ট।
(ব্যাশ 4.4.12 (1) -release মধ্যে) একটি ফাংশন কল করা হচ্ছে কিছুই f1(){ :; }
হাজার গুণ করা হয় তুলনায় ধীর :
কিন্তু শুধুমাত্র যদি সংজ্ঞায়িত আর্গুমেন্ট পিতা বা মাতা ফাংশন কলিং, কেন?
#!/bin/bash
TIMEFORMAT='real: %R'
f1 () { :; }
f2 () {
echo " args = $#";
printf '1 function no args yes '; time for ((i=1;i<$n;i++)); do : ; done
printf '2 function yes args yes '; time for ((i=1;i<$n;i++)); do f1 ; done
set --
printf '3 function yes args no '; time for ((i=1;i<$n;i++)); do f1 ; done
echo
}
main1() { set -- $(seq $m)
f2 ""
f2 "$@"
}
n=1000; m=20000; main1
এর ফলাফল test1
:
args = 1
1 function no args yes real: 0.013
2 function yes args yes real: 0.024
3 function yes args no real: 0.020
args = 20000
1 function no args yes real: 0.010
2 function yes args yes real: 20.326
3 function yes args no real: 0.019
ফাংশনে কোনও যুক্তি বা ইনপুট বা আউটপুট ব্যবহৃত হয় না f1
, হাজার (1000) এর একটি ফ্যাক্টরের বিলম্ব অপ্রত্যাশিত। 1
পরীক্ষাগুলি কয়েকটি শেলগুলিতে প্রসারিত করা, ফলাফলগুলি সামঞ্জস্যপূর্ণ, বেশিরভাগ শেলগুলির কোনও অসুবিধা হয় না বা বিলম্ব হয় না (একই এন এবং এম ব্যবহৃত হয়):
test2(){
for sh in dash mksh ksh zsh bash b50sh
do
echo "$sh" >&2
# \time -f '\t%E' seq "$m" >/dev/null
# \time -f '\t%E' "$sh" -c 'set -- $(seq '"$m"'); for i do :; done'
\time -f '\t%E' "$sh" -c 'f(){ :;}; while [ "$((i+=1))" -lt '"$n"' ]; do : ; done;' $(seq $m)
\time -f '\t%E' "$sh" -c 'f(){ :;}; while [ "$((i+=1))" -lt '"$n"' ]; do f ; done;' $(seq $m)
done
}
test2
ফলাফল:
dash
0:00.01
0:00.01
mksh
0:00.01
0:00.02
ksh
0:00.01
0:00.02
zsh
0:00.02
0:00.04
bash
0:10.71
0:30.03
b55sh # --without-bash-malloc
0:00.04
0:17.11
b56sh # RELSTATUS=release
0:00.03
0:15.47
b50sh # Debug enabled (RELSTATUS=alpha)
0:04.62
xxxxxxx More than a day ......
seq
যুক্তি তালিকার কোনওটিই বা প্রক্রিয়াজাতকরণ বিলম্বের জন্য উত্স নয় তা নিশ্চিত করার জন্য অন্য দুটি পরীক্ষার অভিযোগ ছাড়াই কমেন্ট করুন ।
1 এটাজানা যায় আর্গুমেন্ট দ্বারা ফলাফল ক্ষণস্থায়ী সঞ্চালনের সময় বৃদ্ধি হবে। ধন্যবাদ@ এসএমএল