প্রতিধ্বনি এবং বিড়ালের সম্পাদনের সময়টিতে কেন এইরকম পার্থক্য রয়েছে?


15

এই প্রশ্নের উত্তরের ফলে আমাকে আরও একটি প্রশ্ন জিজ্ঞাসা করতে হয়েছিল:
আমি ভেবেছিলাম নিম্নলিখিত স্ক্রিপ্টগুলি একই কাজ করবে এবং দ্বিতীয়টি আরও দ্রুত হওয়া উচিত, কারণ প্রথমটি ব্যবহার করে catযে ফাইলটি বার বার খোলার প্রয়োজন হয় তবে দ্বিতীয়টি কেবল ফাইলটি খোলায় এক সময় এবং তারপর কেবল একটি পরিবর্তনশীল প্রতিধ্বনি:

(সঠিক কোডের জন্য আপডেট বিভাগটি দেখুন))

প্রথম:

#!/bin/sh
for j in seq 10; do
  cat input
done >> output

দ্বিতীয়ত:

#!/bin/sh
i=`cat input`
for j in seq 10; do
  echo $i
done >> output

যখন ইনপুট প্রায় 50 মেগাবাইট।

তবে আমি যখন দ্বিতীয়টির চেষ্টা করলাম, এটি খুব ধীর ছিল কারণ ভেরিয়েবল প্রতিধ্বনি iকরা একটি বিশাল প্রক্রিয়া ছিল। আমি দ্বিতীয় স্ক্রিপ্টেও কিছু সমস্যা পেয়েছি, উদাহরণস্বরূপ আউটপুট ফাইলের আকার প্রত্যাশার চেয়ে কম ছিল।

আমিও লোক পৃষ্ঠা চেক করা echoএবং catতাদের তুলনা করুন:

প্রতিধ্বনি - পাঠ্যের একটি লাইন প্রদর্শন করুন

বিড়াল - স্ট্যান্ডার্ড আউটপুট উপর ফাইল এবং মুদ্রণ

তবে আমি পার্থক্যটি পেলাম না।

তাই:

  • কেন বিড়াল এত দ্রুত এবং দ্বিতীয় স্ক্রিপ্টে প্রতিধ্বনি এত ধীর?
  • নাকি ভেরিয়েবল নিয়ে সমস্যা i? (কারণ এর ম্যান পেজে echoএটি "পাঠ্যের একটি লাইন" প্রদর্শন করে এবং তাই আমার ধারণা এটি খুব ছোট ভেরিয়েবলের মতো নয় i, তবে এটি কেবল সংক্ষিপ্ত ভেরিয়েবলের জন্য অনুকূলিত হয়েছে However তবে এটি কেবল অনুমান মাত্র))
  • এবং কেন আমি ব্যবহার করতে গিয়ে সমস্যা পেয়েছি echo?

হালনাগাদ

আমি seq 10পরিবর্তে `seq 10`ভুল ব্যবহার করেছি । এটি সম্পাদিত কোড:

প্রথম:

#!/bin/sh
for j in `seq 10`; do
  cat input
done >> output

দ্বিতীয়ত:

#!/bin/sh
i=`cat input`
for j in `seq 10`; do
  echo $i
done >> output

( রইমাকে বিশেষ ধন্যবাদ ।)

তবে এটি সমস্যার মূল বিষয় নয়। লুপটি কেবল একবারে ঘটে গেলেও আমি একই সমস্যা পাই: এর catচেয়ে অনেক দ্রুত কাজ করে echo


1
এবং কি সম্পর্কে cat $(for i in $(seq 1 10); do echo "input"; done) >> output? :)
নেটমোনক

2
echoদ্রুততর। আপনি যা হারিয়েছেন তা হ'ল আপনি যখন শেলটি ব্যবহার করেন তখন ভেরিয়েবলগুলি উদ্ধৃত না করে খুব বেশি কাজ করে যাচ্ছেন।
রোয়াইমা

ভেরিয়েবলগুলি উদ্ধৃত করা সমস্যা নয়; সমস্যাটি হ'ল আমি নিজেই পরিবর্তনশীল (যেমন এটি ইনপুট এবং আউটপুট মধ্যে মধ্যবর্তী পদক্ষেপ হিসাবে ব্যবহার করে)।
আলেকসান্দার

cho প্রতিধ্বনি $ i` - এটি করবেন না। প্রিন্টফ ব্যবহার করুন এবং যুক্তিটি উদ্ধৃত করুন।
পিএসকোকিক

1
@ স্পস্কিক আমি যা বলছি তা আপনি চান printf '%s' "$i", তা নয় echo $i। @ কুওগলম তার উত্তরে প্রতিধ্বনিগুলির কিছু সমস্যা বর্ণনা করেছেন। প্রতিধ্বনির সাথে কিছু ক্ষেত্রে এমনকি উদ্ধৃতিও
প্রশ্নগুলি /

উত্তর:


24

এখানে বেশ কয়েকটি বিষয় বিবেচনা করতে হবে।

i=`cat input`

ব্যয়বহুল হতে পারে এবং শাঁসের মধ্যে অনেকগুলি প্রকরণ রয়েছে।

এটি কমান্ড সাবস্টিটিউশন নামে পরিচিত feature ধারণাটি হ'ল কমান্ডের পুরো আউটপুটটি মাইনাসের পিছনে থাকা নতুন লাইনের অক্ষরগুলিকে iমেমরির ভেরিয়েবলের মধ্যে সঞ্চয় করা হবে।

এটি করার জন্য, শেলগুলি একটি সাবশেলে কমান্ডটি কাঁটাচামচ করে এবং পাইপ বা সকেটপায়ের মাধ্যমে তার আউটপুটটি পড়ে। আপনি এখানে প্রচুর প্রকরণ দেখতে পান। এখানে একটি 50MiB ফাইলে, আমি উদাহরণস্বরূপ ব্যাশটি দেখতে পাচ্ছি ksh93 এর চেয়ে 6 গুণ ধীর কিন্তু zsh এর চেয়ে সামান্য দ্রুত এবং দ্বিগুণ দ্রুত yash

bashধীর হওয়ার মূল কারণ হ'ল এটি পাইপটি একবারে 128 বাইট থেকে পড়ে (অন্য শেলগুলি একবারে 4KiB বা 8KiB পড়ে) এবং সিস্টেম কল ওভারহেড দ্বারা দণ্ডিত হয়।

zshNUL বাইট (অন্যান্য শেলগুলি NUL বাইটে ভেঙে যায়) এড়াতে কিছু পোস্ট-প্রসেসিং করা yashদরকার এবং মাল্টি-বাইট অক্ষরগুলি বিশ্লেষণ করে আরও বেশি ভারী শুল্ক প্রক্রিয়াজাতকরণ করতে হবে।

সমস্ত শেলগুলিকে তারা আরও কম কম দক্ষতার সাথে চালিয়ে যাওয়া লেগেছে নতুন রৈখিক অক্ষরগুলি ফেলা করতে হবে।

কিছু অন্যের চেয়ে NU বাইটগুলি আরও কৃপণভাবে পরিচালনা করতে এবং তাদের উপস্থিতি পরীক্ষা করতে চাইতে পারে।

তারপরে আপনি যখন মেমরিতে বড় আকারের পরিবর্তনশীল হয়ে যান, তখন এটির যে কোনও হেরফেরটিতে সাধারণত আরও মেমরি বরাদ্দ করা এবং জুড়ে ডেটা জুড়ে দেওয়া অন্তর্ভুক্ত।

এখানে, আপনি ভেরিয়েবলের সামগ্রীটি (পাস করার ইচ্ছা করছিলেন) দিয়ে যাচ্ছেন echo

ভাগ্যক্রমে, echoআপনার শেলের মধ্যে অন্তর্নির্মিত, অন্যথায় সম্পাদনা সম্ভবত একটি দীর্ঘ তালিকা ত্রুটির সাথে ব্যর্থ হত । তারপরেও, যুক্তি তালিকা অ্যারে তৈরি করা সম্ভবত ভেরিয়েবলের বিষয়বস্তু অনুলিপি করাতে জড়িত।

আপনার কমান্ড প্রতিস্থাপনের পদ্ধতির অন্য প্রধান সমস্যাটি হ'ল আপনি স্প্লিট + গ্লোব অপারেটরটি (ভেরিয়েবলটি উদ্ধৃত করে ভুলে গিয়ে) ডাকছেন

তার জন্য, শেলগুলি স্ট্রিংটিকে অক্ষরের একটি স্ট্রিং হিসাবে বিবেচনা করতে হবে (যদিও কিছু শেলগুলি সে ক্ষেত্রে বগি না করে) তবে ইউটিএফ -8 লোকেলগুলিতে, এর অর্থ ইউটিএফ -8 সিকোয়েন্সগুলি পার্সিং করা (যদি ইতিমধ্যে এর মতো না করা yashহয়) জন্য তাকান $IFSস্ট্রিং অক্ষর। যদি $IFSস্থান, ট্যাব বা নিউলাইন থাকে (যা পূর্বনির্ধারিত ক্ষেত্রে হয়), তবে অ্যালগোরিদম আরও জটিল এবং ব্যয়বহুল। তারপরে, এই বিভাজনের ফলে যে শব্দগুলি এসেছে তা বরাদ্দ এবং অনুলিপি করা দরকার।

গ্লোব অংশটি আরও ব্যয়বহুল হবে। তাহলে এই কথাগুলো কোন উল্লিখিত glob অক্ষর ( *, ?, [), তারপর শেল কিছু ডিরেক্টরি বিষয়বস্তু পড়তে এবং কিছু দামী প্যাটার্ন ম্যাচিং করতে হবে ( bashউদাহরণস্বরূপ এর বাস্তবায়ন কুখ্যাতিপূর্ণভাবে যে খুব খারাপ)।

যদি ইনপুটটিতে এমন কিছু থাকে তবে এটি /*/*/*/../../../*/*/*/../../../*/*/*অত্যন্ত ব্যয়বহুল হবে যার অর্থ হাজার হাজার ডিরেক্টরিকে তালিকাবদ্ধ করা এবং এটি কয়েকশ এমআইবিতে প্রসারিত হতে পারে।

তারপরে echoসাধারণত কিছু অতিরিক্ত প্রক্রিয়াজাতকরণ করা হবে। কিছু বাস্তবায়ন \xতার প্রাপ্ত আর্গুমেন্টের ক্রমগুলি প্রসারিত করে , যার অর্থ সামগ্রীটি বিশ্লেষণ করা এবং সম্ভবত অন্য একটি বরাদ্দ এবং ডেটা অনুলিপি করা।

অন্যদিকে, ঠিক আছে, বেশিরভাগ শেলগুলিতে catঅন্তর্নির্মিত হয় না, এর অর্থ একটি প্রক্রিয়া তৈরি করা এবং এটি চালানো (সুতরাং কোড এবং লাইব্রেরিগুলি লোড করা) তবে প্রথম অনুরোধের পরে, সেই কোড এবং ইনপুট ফাইলের সামগ্রী স্মরণে রাখা হবে। অন্যদিকে, কোনও মধ্যস্থতাকারী থাকবে না। catএকসাথে বড় পরিমাণে পড়বে এবং প্রসেসিং ছাড়াই সরাসরি লিখে ফেলবে এবং এটি বিপুল পরিমাণ মেমরি বরাদ্দ করার দরকার নেই, কেবলমাত্র এটির একটি বাফার এটি পুনরায় ব্যবহার করে।

এর অর্থ এটিও অনেক বেশি নির্ভরযোগ্য যেহেতু এটি NUL বাইটগুলিতে দম বন্ধ করে না এবং নতুন লাইনের চরিত্রগুলি ছাঁটাই করে না (এবং স্প্লিট + গ্লোব করে না, যদিও আপনি ভেরিয়েবলটি উদ্ধৃত করে এড়াতে পারবেন, এবং না আপনি যদি এর printfপরিবর্তে ব্যবহার করে এড়াতে পারেন তবে পালানোর ক্রমটি প্রসারিত করুন echo)

আপনি যদি এটিকে আরও অনুকূল করতে চান তবে catবেশ কয়েকবার আহ্বান না করে কেবল inputকয়েকবার পাস করুন cat

yes input | head -n 100 | xargs cat

100 এর পরিবর্তে 3 টি কমান্ড চালাবে।

পরিবর্তনশীল সংস্করণটিকে আরও নির্ভরযোগ্য করে তুলতে আপনাকে ব্যবহার করতে হবে zsh(অন্যান্য শেলগুলি NUL বাইটগুলি সহ্য করতে পারে না) এবং এটি করতে হবে:

zmodload zsh/mapfile
var=$mapfile[input]
repeat 10 print -rn -- "$var"

আপনি যদি জানেন যে ইনপুটটিতে NUL বাইট নেই, তবে আপনি নির্ভরযোগ্যভাবে এটি পসিক্সলি করতে পারেন (যদিও এটি যেখানে বিল্টিন নেই সেখানে কাজ করবে printfনা):

i=$(cat input && echo .) || exit # add an extra .\n to avoid trimming newlines
i=${i%.} # remove that trailing dot (the \n was removed by cmdsubst)
n=10
while [ "$n" -gt 10 ]; do
  printf %s "$i"
  n=$((n - 1))
done

তবে এটি কখনই catলুপে ব্যবহারের চেয়ে বেশি দক্ষ হতে পারে না (যদি না ইনপুটটি খুব ছোট হয়)।


এটি উল্লেখ করার মতো বিষয় যে দীর্ঘ তর্ক করার ক্ষেত্রে, আপনি স্মৃতি থেকে বেরিয়ে আসতে পারেন । উদাহরণ/bin/echo $(perl -e 'print "A"x999999')
cuonglm

আপনি এই ধারণার সাথে ভুল হয়ে গেছেন যে পড়ার আকারের একটি উল্লেখযোগ্য প্রভাব রয়েছে, তাই আসল কারণটি বুঝতে আমার উত্তরটি পড়ুন।
সহজেই

@ প্রশংসায়, 128 বাইটের 409600 রিড করা করতে 64৪ কে-র of০০ এর চেয়ে বেশি সময় (সিস্টেমের সময়) লাগে। dd bs=128 < input > /dev/nullসঙ্গে তুলনা করুন dd bs=64 < input > /dev/null। এই ফাইলটি পড়তে 0.6 এর দশকের মধ্যে 0.4 সেগুলি readআমার পরীক্ষাগুলিতে system সিস্টেম কলগুলিতে ব্যয় করা হয় , অন্য শেলগুলি সেখানে খুব কম সময় ব্যয় করে।
স্টাফেন চেজেলাস

ঠিক আছে, আপনি বাস্তবের পারফরম্যান্স বিশ্লেষণ চালিয়েছেন বলে মনে হয় না। পঠন কলের প্রভাব (যখন বিভিন্ন পঠনের মাপের তুলনা করা হয়) হয় এপ্রক্স। যখন ফাংশন পুরো সময় 1% readwc() এবং trim()Burne শেল পুরো সময় 30% গ্রহণ করা এবং এটি সম্ভবত underestimated হয় সেখানে কোন libc হয় gprofজন্য টীকা mbtowc()
স্পষ্টভাবে

কোনটি \xপ্রসারিত হয়?
মোহাম্মদ

11

সমস্যাটি সম্পর্কে নয় catএবং echo, এটা বিস্মৃত উদ্ধৃতি পরিবর্তনশীল সম্পর্কে $i

বোর্নের মতো শেল স্ক্রিপ্টে (ব্যতীত zsh), ভেরিয়েবলগুলিকে ভেরিয়েবলের অকার্যকর কারণ glob+splitঅপারেটরগুলি রেখে ।

$var

এটা আসলে:

glob(split($var))

সুতরাং প্রতিটি লুপ পুনরাবৃত্তির সাহায্যে, input(নতুন পেজগুলি পিছনে ফেলে রাখার) সম্পূর্ণ সামগ্রীটি প্রসারিত, বিভাজন, গ্লোবিং করা হবে। পুরো প্রক্রিয়াটির জন্য মেমরি বরাদ্দ করতে শেল প্রয়োজন, বার বার স্ট্রিংকে পার্স করে। আপনার খারাপ পারফরম্যান্সের কারণেই।

আপনি প্রতিরোধের জন্য ভেরিয়েবলটি উদ্ধৃত করতে পারেন glob+splitতবে এটি আপনাকে বেশি সাহায্য করবে না, যেহেতু শেলটি এখনও বড় স্ট্রিং আর্গুমেন্ট তৈরি করতে এবং এর বিষয়বস্তু স্ক্যান করতে হবে echo(বাহ্যিকের echoসাথে বিল্টিন প্রতিস্থাপন /bin/echoআপনাকে আর্গুমেন্টের তালিকাটি দীর্ঘ দীর্ঘ বা স্মৃতির বাইরে রাখবে) $iআকারের উপর নির্ভর করে )। বেশিরভাগ echoবাস্তবায়ন পসিক্সের অনুগত নয়, এটি প্রাপ্ত তর্কগুলিতে ব্যাকস্ল্যাশ \xক্রমগুলি প্রসারিত করবে ।

এর সাথে cat, শেলটি কেবল প্রতিটি লুপ পুনরাবৃত্তির একটি প্রক্রিয়া চালিত catকরতে পারে এবং অনুলিপি i / o করবে। বিড়াল প্রক্রিয়াটিকে দ্রুততর করতে সিস্টেম ফাইল ফাইল সামগ্রীও ক্যাশে করতে পারে।


2
@ রাইমা: আপনি গ্লোব অংশটি উল্লেখ করেন নি, যা /*/*/*/*../../../../*/*/*/*/../../../../ফাইলের সামগ্রীতে থাকতে পারে এমন কোনও চিত্রের বিশাল কারণ হতে পারে। শুধু বিশদটি উল্লেখ করতে চাই ।
cuonglm

আপনাকে ধন্যবাদ। এমনকি এটি ছাড়াও, অব্যক্ত চলকটি ব্যবহার করার সময় সময় দ্বিগুণ হয়
রোয়াইমা

1
time echo $( <xdditg106) >/dev/null real 0m0.125s user 0m0.085s sys 0m0.025s time echo "$( <xdditg106)" >/dev/null real 0m0.047s user 0m0.016s sys 0m0.022s
নেটমোনক

কেন পাইনি সমস্যাটি সমাধান করতে পারে না তা আমি পাইনি। আমার আরও বিবরণ দরকার।
মোহাম্মদ

1
@ মোহাম্মদ. কে: আমি আমার উত্তরে যেমন লিখেছি, উদ্ধৃতি ভেরিয়েবল glob+splitঅংশটি প্রতিরোধ করে এবং এটি লুপটি দ্রুততর করবে। এবং আমি আরও উল্লেখ করেছি যে এটি আপনাকে খুব বেশি সাহায্য করবে না। যেহেতু বেশিরভাগ শেল echoআচরণ POSIX অনুগত হয় না। printf '%s' "$i"ভাল.
cuonglm

2

ফোন দিলে

i=`cat input`

এটি আপনার শেল প্রক্রিয়াটিকে 200MB (অভ্যন্তরীণ প্রশস্ত অক্ষরের প্রয়োগের উপর নির্ভর করে) 50MB দ্বারা বাড়তে দেয়। এটি আপনার শেলটি ধীর করে দিতে পারে তবে এটি মূল সমস্যা নয়।

মূল সমস্যাটি হ'ল উপরের কমান্ডটি পুরো ফাইলটি শেল মেমরিতে পড়তে হবে এবং echo $iসেই ফাইলের সামগ্রীতে ফিল্ড বিভাজন করা দরকার $i। ক্ষেত্রের বিভাজন করতে, ফাইল থেকে সমস্ত পাঠ্যকে প্রশস্ত অক্ষরে রূপান্তর করা দরকার এবং এখানেই বেশিরভাগ সময় ব্যয় করা হয়।

আমি স্লো কেস নিয়ে কিছু পরীক্ষা করেছি এবং এই ফলাফলগুলি পেয়েছি:

  • দ্রুততমটি ksh93
  • এরপরে আমার বোর্ন শেল (2x ধীর যে ksh93)
  • এরপরে বাশ রয়েছে (ksh93 এর চেয়ে 3x ধীর)
  • শেষটি ksh88 (ksh93 এর চেয়ে 7x ধীর)

Ksh93 দ্রুত হওয়ার কারণটি মনে হয় যে ksh93 libc mbtowc()থেকে ব্যবহার করে না বরং একটি নিজস্ব বাস্তবায়ন করেছে।

বিটিডাব্লু: স্টিফেন ভুল করে পড়েছে যে পড়ার আকারের কিছু প্রভাব রয়েছে, আমি বোর্ন শেলকে 128 বাইটের পরিবর্তে 4096 বাইট খণ্ডে পড়ার জন্য সংকলিত করেছিলাম এবং উভয় ক্ষেত্রেই একই পারফরম্যান্স পেয়েছি।


i=`cat input`কমান্ড ক্ষেত্র বিভাজন করে না, এটা echo $iযে আছে। ব্যয় করা সময়টি i=`cat input`তুলনায় তুচ্ছ হবে echo $i, তবে cat inputএকার সাথে তুলনা করা হবে না এবং এর ক্ষেত্রে ছোট ছোট পাঠ bashকরার কারণে পার্থক্যটি সেরা অংশের জন্য bash। 128 থেকে 4096 থেকে পরিবর্তন করা এর পারফরম্যান্সে কোনও প্রভাব ফেলবে না echo $i, তবে এটি আমি তৈরি করছিলাম না।
স্টাফেন চেজেলাস

এছাড়াও নোট করুন যে echo $iইনপুট এবং ফাইল সিস্টেমের (যদি এটিতে আইএফএস বা গ্লোব অক্ষর রয়েছে) এর উপর নির্ভর করে এর পারফরম্যান্স যথেষ্ট পরিমাণে পৃথক হবে, যার কারণেই আমি আমার উত্তরে শেলের কোনও তুলনা করিনি। উদাহরণস্বরূপ, এখানে আউটপুট হিসাবে yes | ghead -c50M, ksh93 হ'ল সকলের মধ্যে সবচেয়ে ধীর, তবে yes | ghead -c50M | paste -sd: -এটি দ্রুততম।
স্টাফেন চেজেলাস

মোট সময় সম্পর্কে কথা বলার সময়, আমি পুরো বাস্তবায়ন সম্পর্কে কথা বলছিলাম এবং হ্যাঁ অবশ্যই ক্ষেত্র বিভাজন ইকো কমান্ডের সাথে ঘটে। এবং এখানেই বেশিরভাগ সময় ব্যয় করা হয়।
সহজেই 17'15

আপনি অবশ্যই সঠিক যে কর্মক্ষমতা od $ i বিষয়বস্তুর উপর নির্ভর করে।
সহজেই

1

উভয় ক্ষেত্রে লুপটি কেবল দু'বার চালিত হবে (একবার শব্দের জন্য seqএবং একবার শব্দের জন্য 10)।

ফিউটারমোর উভয়ই সংলগ্ন হোয়াইটস্পেসকে একীভূত করবে এবং শীর্ষস্থানীয় / পিছনের হোয়াইটস্পেসটি ড্রপ করবে, যাতে আউটপুটটি প্রয়োজনীয়ভাবে ইনপুটটির দুটি অনুলিপি না হয়।

প্রথম

#!/bin/sh
for j in $(seq 10); do
    cat input
done >> output

দ্বিতীয়

#!/bin/sh
i="$(cat input)"
for j in $(seq 10); do
    echo "$i"
done >> output

কারণটি echoধীর হওয়ার কারণ হ'ল আপনার উদাতীত ভেরিয়েবলটি শ্বেত স্পেসে পৃথক শব্দের মধ্যে বিভক্ত করা হচ্ছে। 50MB এর জন্য এটি অনেক কাজ হবে। ভেরিয়েবলের উদ্ধৃতি!

আমি আপনাকে এই ত্রুটিগুলি ঠিক করার পরামর্শ দিই এবং তারপরে আপনার সময়গুলি পুনরায় মূল্যায়ন করুন।


আমি স্থানীয়ভাবে এটি পরীক্ষা করেছি। এর আউটপুট ব্যবহার করে আমি একটি 50MB ফাইল তৈরি করেছি tar cf - | dd bs=1M count=50। আমি এক্স 100 এর একটি ফ্যাক্টর দ্বারা চালিত করতে লুপগুলি প্রসারিত করেছিলাম যাতে সময়গুলি একটি যুক্তিসঙ্গত মান হিসাবে স্কেল করা যায় (আমি আপনার পুরো কোডের চারপাশে আরও লুপ যুক্ত করেছি: for k in $(seq 100); do... done)। সময়গুলি এখানে:

time ./1.sh

real    0m5.948s
user    0m0.012s
sys     0m0.064s

time ./2.sh

real    0m5.639s
user    0m4.060s
sys     0m0.224s

আপনি দেখতে পাচ্ছেন যে কোনও আসল পার্থক্য নেই, তবে কিছু থাকলে সংস্করণটি echoসামান্য দ্রুত চলে। যদি আমি কোটগুলি সরিয়ে নিয়ে যাই এবং আপনার ভাঙা সংস্করণ 2 টি দ্বিগুণ করার সময় এটি চালিয়ে যায় যে শেলটি আরও অনেক বেশি কাজ করতে পারে যা প্রত্যাশা করা উচিত।

time ./2original.sh

real    0m12.498s
user    0m8.645s
sys     0m2.732s

লুপটি 10 ​​বার চলে, দু'বার নয়।
fpmurphy

আপনি যেমন বলেছিলেন তেমনটি করেছি, তবে সমস্যাটির সমাধান হয়নি। catতুলনায় খুব দ্রুত echo। প্রথম স্ক্রিপ্টটি গড়ে 3 সেকেন্ডে চলে, তবে দ্বিতীয়টি 54 সেকেন্ডের গড়ে রান করে।
মোহাম্মদ

@ fpmurphy1: না আমি আমার কোড চেষ্টা করেছিলাম। লুপটি 10 ​​বার নয়, কেবল দু'বার চালায়।
মোহাম্মদ

@ মোহাম্মদ.কম তৃতীয়বারের মতো: আপনি যদি আপনার ভেরিয়েবলগুলি উদ্ধৃত করেন, সমস্যাটি চলে যায়।
রোয়াইমা

@ রাইমা: কমান্ড কী করে tar cf - | dd bs=1M count=50? এটির ভিতরে একই অক্ষরগুলি দিয়ে একটি নিয়মিত ফাইল তৈরি করে? যদি তা হয় তবে আমার ক্ষেত্রে ইনপুট ফাইলটি সমস্ত ধরণের অক্ষর এবং সাদা স্থানের সাথে সম্পূর্ণ অনিয়মিত। এবং আবারও, timeআপনি যেমন ব্যবহার করেছেন তেমন ব্যবহার করেছি, এবং ফলাফলটি আমি বলেছিলাম: 54 সেকেন্ড বনাম 3 সেকেন্ড।
মোহাম্মদ

-1

read তুলনায় অনেক দ্রুত cat

আমি মনে করি সবাই এটি পরীক্ষা করতে পারে:

$ cd /sys/devices/system/cpu/cpu0/cpufreq
───────────────────────────────────────────────────────────────────────────────────────────
$ time for ((i=0; i<10000; i++ )); do read p < scaling_cur_freq ; done

real    0m0.232s
user    0m0.139s
sys     0m0.088s
───────────────────────────────────────────────────────────────────────────────────────────
$ time for ((i=0; i<10000; i++ )); do cat scaling_cur_freq > /dev/null ; done

real    0m9.372s
user    0m7.518s
sys     0m2.435s
───────────────────────────────────────────────────────────────────────────────────────────
$ type -a read
read is a shell builtin
───────────────────────────────────────────────────────────────────────────────────────────
$ type -a cat
cat is /bin/cat

cat9.372 সেকেন্ড সময় নেয়। কয়েক সেকেন্ড echoসময় লাগে .232

readহয় 40 বার দ্রুত

$pস্ক্রিনে প্রতিধ্বনিত হওয়ার পরে আমার প্রথম পরীক্ষাটি read48 গুণ বেশি দ্রুত ছিল cat


-2

এর echoঅর্থ স্ক্রিনে 1 লাইন লাগানো। দ্বিতীয় উদাহরণে আপনি যা করেন তা হ'ল আপনি ফাইলের বিষয়বস্তুকে একটি ভেরিয়েবলে রেখেছিলেন এবং তারপরে আপনি সেই পরিবর্তনশীলটি মুদ্রণ করেন। প্রথমটিতে আপনি তত্ক্ষণাত্ সামগ্রীটি স্ক্রিনে রেখেছিলেন।

catএই ব্যবহারের জন্য অনুকূলিত হয়। echoএটি না. 50Mb এনভায়রনমেন্ট ভেরিয়েবলে রাখা ভাল ধারণা নয়।


অদ্ভুত। echoপাঠ্য লেখার জন্য কেন অনুকূলিত হবে না ?
রোয়াইমা

2
পসিক্স স্ট্যান্ডার্ডে এমন কোনও কিছুই নেই যা বলে যে প্রতিধ্বনি বলতে পর্দায় একটি লাইন লাগানো।
এফএমপুরফি

-2

এটি প্রতিধ্বনি দ্রুত হওয়ার বিষয়ে নয়, আপনি কী করছেন সে সম্পর্কে এটি:

একটি ক্ষেত্রে আপনি ইনপুট থেকে পড়া এবং সরাসরি আউটপুট লিখছেন। অন্য কথায়, বিড়ালের মাধ্যমে ইনপুট থেকে যা কিছু পড়া হয় তা স্টাডাউটের মাধ্যমে আউটপুটে যায়।

input -> output

অন্য ক্ষেত্রে আপনি ইনপুট থেকে মেমরির একটি ভেরিয়েবলের মধ্যে পড়ছেন এবং তারপরে আউটপুটটিতে ভেরিয়েবলের বিষয়বস্তু লিখছেন।

input -> variable
variable -> output

পরেরটি অনেক ধীর হবে, বিশেষত যদি ইনপুট 50MB হয়।


আমি মনে করি আপনাকে উল্লেখ করতে হবে যে বিড়ালকে স্টিডিন থেকে অনুলিপি করা এবং স্টডআউটে লেখার পাশাপাশি ফাইলটিও খুলতে হবে। এটি দ্বিতীয় স্ক্রিপ্টের শ্রেষ্ঠত্ব, তবে প্রথমটি মোট দ্বিতীয়টির চেয়ে খুব ভাল better
মোহাম্মদ

দ্বিতীয় স্ক্রিপ্টে কোনও শ্রেষ্ঠত্ব নেই; বিড়াল উভয় ক্ষেত্রে ইনপুট ফাইল খুলতে হবে। প্রথম ক্ষেত্রে বিড়ালের stdout সরাসরি ফাইলে যায়। দ্বিতীয় ক্ষেত্রে বিড়ালের stdout প্রথমে একটি পরিবর্তনশীল যায় এবং তারপরে আপনি ভেরিয়েবলটি আউটপুট ফাইলে মুদ্রণ করেন।
আলেকসান্দার

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