পিএইচপি-তে ফর বনাম ফোর-এর পারফরম্যান্স


134

প্রথমত, আমি 90% অ্যাপ্লিকেশনগুলিতে বুঝতে পারি পারফরম্যান্সের পার্থক্যটি সম্পূর্ণ অপ্রাসঙ্গিক, তবে আমার কেবলমাত্র দ্রুত নির্মাণ কোনটি তা জানতে হবে। যে এবং ...

নেটে তাদের কাছে বর্তমানে উপলব্ধ তথ্য বিভ্রান্তিকর। প্রচুর লোক বলেছেন ফোরঞ্চ খারাপ, তবে প্রযুক্তিগতভাবে এটি দ্রুত হওয়া উচিত কারণ এটি মনে করা হয় যে এটিরেটরগুলি ব্যবহার করে একটি অ্যারে ট্র্যাভারসাল লেখা সহজ করা যায়। Iteters, যা আবার মনে হয় দ্রুত হয়, কিন্তু পিএইচপি মধ্যে স্পষ্টতই মৃত ধীর (বা এটি একটি পিএইচপি জিনিস না?)। আমি অ্যারে ফাংশনগুলির বিষয়ে বলছি: পরের () পূর্ব () পূর্ববর্তী () পুনরায় সেট করুন () ইত্যাদি ভাল, যদি তারা এমনকি ফাংশন হয় এবং সেই পিএইচপি ভাষার বৈশিষ্ট্যগুলির মধ্যে একটিও নয় যা ফাংশনগুলির মতো দেখায়।

এটিকে কিছুটা সংকুচিত করার জন্য : আমি 1 এর চেয়ে বেশি কোনও পদক্ষেপে অ্যারেগুলি ঘুরে বেড়ানো সম্পর্কে আকর্ষণীয় নই (কোনও নেতিবাচক পদক্ষেপ নয়, অর্থাৎ বিপরীত পুনরাবৃত্তি)। আমি কেবল 0 দৈর্ঘ্য থেকে নির্বিচার পয়েন্টগুলিতে এবং ট্র্যাভারসাল সম্পর্কে আগ্রহী নই। আমি নিয়মিতভাবে 1000 টিরও বেশি কীগুলির সাথে অ্যারে হেরফের করতে দেখি না, তবে আমি দেখতে পাচ্ছি যে কোনও অ্যারের অ্যাপ্লিকেশনটির যুক্তিতে একাধিকবার অতিক্রম করা হচ্ছে! অপারেশন হিসাবে, মূলত শুধুমাত্র স্ট্রিং ম্যানিপুলেশন এবং প্রতিধ্বনিত।

এখানে কয়েকটি রেফারেন্স সাইট রয়েছে:
http://www.phpbench.com/
http://www.php.lt/benchmark/phpbench.php

যা আমি সর্বত্র শুনি:

  • foreachধীর এবং এইভাবে for/ whileদ্রুত হয় /
  • পিএইচপিগুলি foreachএটির পুনরাবৃত্তি করে এমন অ্যারের অনুলিপি করে; এটিকে দ্রুত করতে আপনার উল্লেখগুলি ব্যবহার করা দরকার
  • এর মতো কোড: একটির চেয়ে দ্রুত$key = array_keys($aHash); $size = sizeOf($key);
    for ($i=0; $i < $size; $i++)
    foreach

এখানে আমার সমস্যা। আমি এই পরীক্ষার স্ক্রিপ্টটি লিখেছি: http://pastebin.com/1ZgK07US এবং আমি স্ক্রিপ্টটি যতবার চালাই না কেন, আমি এরকম কিছু পাই:

foreach 1.1438131332397
foreach (using reference) 1.2919359207153
for 1.4262869358063
foreach (hash table) 1.5696921348572
for (hash table) 2.4778981208801

সংক্ষেপে:

  • foreachforeachরেফারেন্স তুলনায় দ্রুত
  • foreach তুলনায় দ্রুত for
  • foreachforহ্যাশ টেবিলের চেয়ে দ্রুত

কেউ কি ব্যাখ্যা করতে পারেন?

  1. আমি কি ভুল কিছু করছি?
  2. পিএইচপি ফোরচ রেফারেন্স জিনিসটি কি সত্যিই কোনও পার্থক্য আনছে? মানে আপনি যদি রেফারেন্স দিয়ে পাস করেন তবে কেন এটি অনুলিপি করবেন না?
  3. ফরচ স্টেটমেন্টের সমতুল্য পুনরাবৃত্তকারী কোডটি কী; আমি নেটে কয়েকটি দেখেছি তবে প্রতিবারই আমি তাদের পরীক্ষা করে দেখছি সময়টি বন্ধ হয়ে গেছে; আমি কয়েকটি সাধারণ পুনরাবৃত্তকারী নির্মাণও পরীক্ষা করেছি তবে কখনও উপযুক্ত ফলাফল পাবে বলে মনে হয় না - পিএইচপি-তে অ্যারে পুনরাবৃত্তিগুলি কি ভয়াবহ?
  4. ফর / ফরচার (এবং WHIL) ব্যতীত অন্য কোনও অ্যারে থাকলেও পুনরাবৃত্তি করার জন্য কি আরও দ্রুত উপায় / পদ্ধতি / গঠন রয়েছে?

পিএইচপি সংস্করণ 5.3.0


সম্পাদনা: উত্তর এখানকার লোকদের সহায়তায় আমি সমস্ত প্রশ্নের উত্তর একসাথে করতে সক্ষম হয়েছি। আমি তাদের এখানে সংক্ষেপ করব:

  1. "আমি কি ভুল কিছু করছি?" Sensকমত্য বলে মনে হচ্ছে: হ্যাঁ, আমি বেঞ্চমার্কে প্রতিধ্বনি ব্যবহার করতে পারি না। ব্যক্তিগতভাবে, আমি এখনও দেখতে পাচ্ছি না যে মৃত্যুর নির্ধারিত সময়ের সাথে প্রতিধ্বনি কিছু ফাংশন কীভাবে বা অন্য কোনও ফাংশন কীভাবে অন্যরকম হয় - যা এবং সেই স্ক্রিপ্টটির দক্ষতা ঠিক সমস্ত কিছুের চেয়ে ঠিক ঠিক একই ফলাফল উত্পন্ন করতে পারে যদিও "আপনি প্রতিধ্বনি ব্যবহার করছেন" ঠিক আছে তা বোঝাতে (ভাল করে আমার কী ব্যবহার করা উচিত ছিল)। তবে, আমি স্বীকার করি পরীক্ষা আরও ভাল কিছু করা উচিত; যদিও একটি আদর্শ আপস মাথায় আসে না।
  2. "পিএইচপি ফোরচ রেফারেন্সের জিনিসটি কি আসলেই কোনও পার্থক্য আনছে? মানে আপনি যদি রেফারেন্স দিয়ে পাস করেন তবে এটি কেন এটি অনুলিপি করবে না?" আর্কম্যাক্সেল দেখায় যে হ্যাঁ, এটি আরও পরীক্ষার মাধ্যমে প্রমাণিত হয় যে বেশিরভাগ ক্ষেত্রে রেফারেন্সটি দ্রুত হওয়া উচিত - যদিও আমার উপরের কোডের স্নিপেট দেওয়া হয়েছে, অবশ্যই স্পষ্টভাবে সমস্তটি বোঝায় না। আমি গ্রহণ করি যে বিষয়টি সম্ভবত এ জাতীয় স্তরে বিরক্ত করার জন্য খুব স্বজ্ঞাত নয় এবং প্রতিটি অবস্থার জন্য কোনটি আরও ভাল তা নির্ধারণ করার জন্য পচানোর মতো চূড়ান্ত কিছু প্রয়োজন হবে।
  3. "ভবিষ্যদ্বাণী বিবৃতিটির সমতুল্য পুনরাবৃত্তকারী কোডটি কী; আমি নেটে কয়েকটি দেখেছি কিন্তু প্রতিবারই তাদের পরীক্ষা করে দেখছি সময়টি বন্ধ is - পিএইচপি-তে অ্যারে পুনরাবৃত্তিকারী কি কেবল ভয়ঙ্কর? " আইআরম্যাক্সেল উত্তরটি নমুনা সরবরাহ করেছে; যদিও কোডটি কেবল পিএইচপি সংস্করণ> = 5 এর জন্য বৈধ হতে পারে
  4. "ফর / ফরচার (এবং WHIL) ব্যতীত অন্য কোনও অ্যারে হলেও পুনরাবৃত্তি করার জন্য কি আরও দ্রুত উপায় / পদ্ধতি / গঠন রয়েছে?" উত্তরের জন্য গর্ডনের কাছে ধন্যবাদ। পিএইচপি 5 এ নতুন ডেটা প্রকারের ব্যবহারের ক্ষেত্রে পারফরম্যান্স বুস্ট বা মেমরি বুস্ট দেওয়া উচিত (যার মধ্যে কোনওটি আপনার পরিস্থিতির উপর নির্ভর করে কাঙ্ক্ষিত হতে পারে)। যদিও গতি অনুসারে নতুন ধরণের অ্যারের অনেকগুলি অ্যারে () এর চেয়ে ভাল বলে মনে হয় না, তবে স্প্ল্পপ্রিয়রিটিকিউ এবং স্প্লোবজেক্টটোরেজ যথেষ্ট গতিযুক্ত বলে মনে হয়। গর্ডন সরবরাহ করেছেন লিঙ্ক: http://matthewturland.com/2010/05/20/new-spl-features-in-php-5-3/

যারা সাহায্য করার চেষ্টা করেছেন তাদের সবাইকে ধন্যবাদ।

আমি সম্ভবত কোনও সহজ ট্রভারসাল জন্য ভবিষ্যদ্বাণী (অ-রেফারেন্স সংস্করণ) ধরে থাকব।


7
বেঞ্চমার্কিংয়ের ২.71১ বিধি: বেঞ্চমার্কে প্রতিধ্বনি করবেন না।
Mchl

1
রেফারেন্স সহ foreach অবশ্যই রেফারেন্সের সাথে বিরুদ্ধে bechmarking করা আবশ্যক। আপনি এখানে একটি ত্রুটিযুক্ত উপসংহার আছে। রেফারেন্সের কোনও ব্যবহার স্পষ্টতই রেফারেন্স ছাড়াই ধীর হতে চলেছে, এমনকি একটি ডু-ওয়েল লুপেও।
bcosca

2
যেহেতু এটি পিএইচপি 5.3 এর জন্য, আপনি নতুন স্প্লাল ডেটা প্রকার বনাম অ্যারে পরীক্ষা করার বিষয়টি বিবেচনা করতে পারেন। বা কেবল এখানে দেখুন: ম্যাথিউথুরল্যান্ড.com
গর্ডন

@ এমচএল: আমি এটি কয়েকবার দৌড়েছি, এবং একই ফলাফল পেয়েছি - যদি প্রতিধ্বনিটি মাপদণ্ডকে দূষিত করে তোলে তবে আমার কি সম্পূর্ণ এলোমেলো ফলাফল পাওয়া উচিত নয়? এছাড়াও আমি পুনরাবৃত্তি করতে চাই যদিও কিছু এবং আউটপুট এটি তাই প্রতিধ্বনি আমার জন্য সত্যই গুরুত্বপূর্ণ; যদি প্রতিধ্বনি করার সময় যদি ফোরচ দ্রুত হয় তবে এটি কোডের একটি বড় অংশ যেখানে আমার পূর্বাচ ব্যবহার করা উচিত। @ স্থিরতা: আমি যা শুনছি তা মূলত "পূর্ববর্তী রেফারেন্সটি দ্রুত করে তোলে (সর্বদা), সর্বদা রেফারেন্স দিয়ে লিখি", এ কারণেই আমি এরকম পরীক্ষা করেছি - অন্যান্য রেফারেন্স লুপগুলির সাথে তুলনা করতে আমি সত্যিই আগ্রহী নই
srcspider

2
এই খালি প্রশ্নগুলি স্বাভাবিকভাবেই নিষিদ্ধ করা উচিত। পাশাপাশি সেই প্রতারণামূলক phpbench সাইট
আপনার প্রচলিত

উত্তর:


110

আমার ব্যক্তিগত মতামতটি প্রসঙ্গে যেটি বোঝায় তা ব্যবহার করা। ব্যক্তিগতভাবে আমি প্রায় কখনও forঅ্যারে ট্র্যাভারসাল জন্য ব্যবহার করি না । আমি এটি অন্যান্য ধরণের পুনরাবৃত্তির জন্য ব্যবহার করি তবে foreachএটি খুব সহজ ... বেশিরভাগ ক্ষেত্রে সময়ের পার্থক্য ন্যূনতম হতে চলেছে।

দেখার জন্য বড় বিষয় হ'ল:

for ($i = 0; $i < count($array); $i++) {

এটি একটি ব্যয়বহুল লুপ, যেহেতু এটি প্রতিটি একক পুনরাবৃত্তিতে গণনা কল করে। আপনি যতক্ষণ না এটি করছেন, ততক্ষণ আমার মনে হয় না এটি সত্যিই গুরুত্বপূর্ণ ...

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

পুনরাবৃত্তিকারীদের foreachসমতুল্য:

$it->rewind();
while ($it->valid()) {
    $key = $it->key();     // If using the $key => $value syntax
    $value = $it->current();

    // Contents of loop in here

    $it->next();
}

যত তাড়াতাড়ি পুনরাবৃত্তি করার দ্রুত উপায় রয়েছে, এটি সত্যিই সমস্যার উপর নির্ভর করে। তবে আমার সত্যিই জিজ্ঞাসা করা দরকার কেন? আমি জিনিসগুলিকে আরও দক্ষ করে তুলতে চাই তা বুঝতে পেরেছি তবে আমি মনে করি আপনি একটি ক্ষুদ্র-অনুকূলকরণের জন্য আপনার সময় নষ্ট করছেন। মনে রাখবেন, Premature Optimization Is The Root Of All Evil...

সম্পাদনা করুন: মন্তব্যের ভিত্তিতে, আমি দ্রুত বেঞ্চমার্ক রান করার সিদ্ধান্ত নিয়েছি ...

$a = array();
for ($i = 0; $i < 10000; $i++) {
    $a[] = $i;
}

$start = microtime(true);
foreach ($a as $k => $v) {
    $a[$k] = $v + 1;
}
echo "Completed in ", microtime(true) - $start, " Seconds\n";

$start = microtime(true);
foreach ($a as $k => &$v) {
    $v = $v + 1;
}
echo "Completed in ", microtime(true) - $start, " Seconds\n";

$start = microtime(true);
foreach ($a as $k => $v) {}
echo "Completed in ", microtime(true) - $start, " Seconds\n";

$start = microtime(true);
foreach ($a as $k => &$v) {}    
echo "Completed in ", microtime(true) - $start, " Seconds\n";

এবং ফলাফল:

Completed in 0.0073502063751221 Seconds
Completed in 0.0019769668579102 Seconds
Completed in 0.0011849403381348 Seconds
Completed in 0.00111985206604 Seconds

সুতরাং আপনি যদি লুপটিতে অ্যারেটি পরিবর্তন করছেন তবে উল্লেখগুলি ব্যবহার করা কয়েকগুণ দ্রুত ...

এবং কেবল রেফারেন্সের জন্য ওভারহেড আসলে অ্যারে অনুলিপি করার চেয়ে কম হয় (এটি 5.3.2 এ রয়েছে) ... সুতরাং এটি প্রদর্শিত হয় (কমপক্ষে 5.3.2 এ) যেন উল্লেখগুলি দ্রুততর হয় ...


1
আপনি কি "[পরিকল্পিত] অপ্টিমাইজেশন হ'ল সমস্ত মন্দের মূল" বলতে চান না? ;) ভাল জিনিস হ'ল তাদের সকলেই একই কাজ করে, সুতরাং এটি এতটা অপ্টিমাইজেশন নয় যা হ'ল "অবলম্বনের সর্বোত্তম মানক উপায়"। এছাড়াও আরও কিছু প্রশ্ন উত্তরহীন: আপনি বলছেন যে এটি অনুলিপি করতে হবে না, তবে রেফারেন্সটির ব্যবহারও ওভারহেড নয়? আমার প্রশ্নে স্থির মন্তব্যটি আপনার অনুমানের সাথেও একমত নয় বলে মনে হচ্ছে। এছাড়াও, কোডটি কেন সেখানে রেফারেন্সের জন্য ধীর হয়। 5.3.0-এ কি কোনও অ্যারে () কোনও অবজেক্টে (উদাহরণস্বরূপ স্প্লিফিক্সডআরে) রূপান্তর করতে পূর্বাচ পরিবর্তন হয়েছিল?
srcspider

@ এসসিআর স্পাইসাইডার: বেঞ্চমার্ক কোড সহ সম্পাদিত উত্তর এবং রেফারেন্সগুলি দেখানো ফলাফলগুলি অ-রেফারেন্সের চেয়ে অনেক দ্রুত ...
ইরক্মেক্সেল

1
@srcspider "the better standard way to adopt." কর্মক্ষমতা কেবল কী গ্রহণ করবেন তা চয়ন করার মানদণ্ড নয়। বিশেষত এ জাতীয় দুর্ঘটনার ক্ষেত্রে। স্পষ্টতই, আপনি কেবল নিজের সময় নষ্ট করছেন
আপনার সাধারণ সংবেদন 'ই

@Col। Shrapnel আমি 100% সম্মত। এই বিশেষ ক্ষেত্রে বড় ব্যবধানে পাঠযোগ্যতা এবং রক্ষণাবেক্ষণযোগ্যতা ট্রাম্পের অভিনয় ... আমি একটি মান বাছাই করা এবং এটির সাথে লেগে থাকার বিষয়ে একমত, তবে সেই মানটি
irc ম্যাক্সেল

@ কিরম্যাক্সেল: দ্রুত আপনার স্ক্রিপ্টটি চালানো আপনার বক্তব্য প্রমাণিত করেছে বলে মনে হচ্ছে তবে আমি এটি আরও খানিকটা দেখতে চাই; আমি আমার মূল প্রশ্নটি নতুন 5.3 বৈশিষ্ট্য সহ আরও পরীক্ষার মাধ্যমে সম্পাদনা করতে পারি। @Col। Shrapnel: জন্য প্রায় সর্বজনীন প্রোগ্রামিং-কিন্ডারগার্ডেন স্তর, ফোরাক সহজ বাক্য গঠন। যতদূর পঠনযোগ্যতা তারা সমান স্থানে রয়েছে বলে মনে হয়। এটি এতটা নিম্ন স্তরের যা আমি মনে করি না যে কোনও উচ্চ স্তরের প্যাটার্নের জন্য রক্ষণাবেক্ষণ কোনও সমস্যা। এবং আমি মনে করি না যে আমি আমার সময় নষ্ট করছি যেহেতু এই "বেসিক কনস্ট্রাক্ট" এর জন্য আমি প্রচুর কোড লিখব। :)
srcspider

54

আমি নিশ্চিত না যে এটি এত আশ্চর্য। বেশিরভাগ লোকেরা যারা পিএইচপি কোড করে তাদের পিএইচপি আসলে বেয়ার মেটালটিতে কী করছে সে সম্পর্কে ভালভাবে পারদর্শী নয়। আমি কয়েকটি বিষয় বর্ণনা করব, যা বেশিরভাগ সময় সত্য হবে:

  1. আপনি যদি ভেরিয়েবলটি পরিবর্তন করছেন না, পিএইচপিতে বাই-মানটি দ্রুত। এর কারণ এটি যাইহোক রেফারেন্স গণনা করা হয় এবং বাই-ভ্যালু এটিকে করতে কম দেয়। এটি যে দ্বিতীয়টি আপনি জেডভিএল (বেশিরভাগ ধরণের জন্য পিএইচপি এর অভ্যন্তরীণ ডেটা কাঠামো) সংশোধন করেছেন তা জানে, এটি একেবারে সরল উপায়ে ভেঙে ফেলতে হবে (এটি অনুলিপি করুন এবং অন্যান্য জেডভিএল সম্পর্কে ভুলে যান)। তবে আপনি কখনই এটি সংশোধন করেন না, তাই এটি কোনও বিষয় নয়। রেফারেন্সগুলি আরও বুককিপিংয়ের সাথে আরও জটিল করে তোলে যখন আপনি ভেরিয়েবলটি পরিবর্তন করেন তখন কী করতে হবে তা জানতে হবে to সুতরাং আপনি যদি কেবলমাত্র পঠনযোগ্য হন তবে বিদ্বেষমূলকভাবে এটি & এর সাথে যে বিন্দুটি নয় সেটাই ভাল। আমি জানি, এটি স্বজ্ঞাত পাল্টা, তবে এটিও সত্য।

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

  3. ($ I = 0; $ i <গণনা ($ x); $ i++) এর জন্য লুপের জন্য "" ব্যবহার করা ধীরে ধীরে গণনা (), এবং পার্সে মূল্যায়ন করার জন্য পিএইচপি-র ক্ষমতা (বা সত্যিই কোনও ব্যাখ্যা করা ভাষা) এর অভাব কোনও কিছু অ্যারে সংশোধন করে কিনা সময়। এটি একবারে গণনাটি মূল্যায়ন করতে বাধা দেয়।

  4. তবে একবারে আপনি "$ সি = গণনা ($ x) দিয়ে এটি ঠিক করেছেন; এর জন্য ($ i = 0; $ i <$ c; $ i ++) $ i <$ সি জেন্ডার ওপোকোডগুলির একগুচ্ছ, যেমনটি রয়েছে $ i ++। 100000 পুনরাবৃত্তির কোর্সে, এটি গুরুত্বপূর্ণ হতে পারে Fore ফোরচ স্থানীয় করণীয়টি কী করতে হবে তা জানে "" আমি এই অ্যারের শেষে আছি "শর্তটি পরীক্ষা করার জন্য কোনও পিএইচপি ওপোকডের প্রয়োজন নেই।

  5. পুরানো স্কুল সম্পর্কে "কী (তালিকা (" স্টাফ? ভাল, প্রতিটি (), কারেন্ট () ইত্যাদি ব্যবহার করা ইত্যাদি) অন্তত 1 টি ফাংশন কল জড়িত হতে চলেছে, যা ধীর নয়, নিখরচায় নয়। হ্যাঁ, সেগুলি আবার পিএইচপি অপকড হয়! সুতরাং যখন + তালিকাগুলি + প্রত্যেকের জন্য তার ব্যয়ও থাকে।

এই কারণে foreach বোধগম্য সহজ পুনরাবৃত্তি জন্য সেরা বিকল্প।

এবং ভুলে যাবেন না, এটি পড়ার পক্ষেও সহজ, তাই এটি জয়-জয়।


ধন্যবাদ, আমি ঠিক এই ব্যাখ্যাটি খুঁজছিলাম, ধন্যবাদ।
হার্ডসেটিং

এই উত্তরটি চিহ্নিত করা উত্তরের জন্য সরবরাহ বা সংক্ষিপ্তসার হওয়া উচিত। আমি আনন্দিত আমি এটি পড়েছি, ভাল কাজ।
ডোজ 87

30

বেঞ্চমার্কগুলিতে (বিশেষত phpbench.com) লক্ষ্য রাখার জন্য একটি জিনিস, সংখ্যাগুলি সুনির্দিষ্ট হলেও টেস্টগুলি হয় না। পিএইচপিঞ্চে ডটকমের পরীক্ষাগুলি খুব কম কাজ করে যা বেঞ্চমার্কগুলিতে স্কিউ করতে অ্যারে লুকআপগুলি ক্যাশে করার জন্য পিএইচপি-র ক্ষমতাকে অপব্যবহার করে বা কোনও অ্যারের উপরে পুনরাবৃত্তি করার ক্ষেত্রে এটি সত্যিকারের বিশ্বের ক্ষেত্রে পরীক্ষা করে না (কেউ খালি লেখেন না বলে লুপ)। আমি আমার নিজস্ব মানদণ্ডগুলি করেছি যা আমি পেয়েছি সত্যিকারের বিশ্বের ফলাফলগুলির প্রতিচ্ছবি এবং তারা সর্বদা ভাষার স্থানীয় পুনরাবৃত্ত বাক্য গঠনটি foreachশীর্ষে উপস্থিত হয় (আশ্চর্য, অবাক করে) দেখায় ।

//make a nicely random array
$aHash1 = range( 0, 999999 );
$aHash2 = range( 0, 999999 );
shuffle( $aHash1 );
shuffle( $aHash2 );
$aHash = array_combine( $aHash1, $aHash2 );


$start1 = microtime(true);
foreach($aHash as $key=>$val) $aHash[$key]++;
$end1 = microtime(true);

$start2 = microtime(true);
while(list($key) = each($aHash)) $aHash[$key]++;
$end2 = microtime(true);


$start3 = microtime(true);
$key = array_keys($aHash);
$size = sizeOf($key);
for ($i=0; $i<$size; $i++) $aHash[$key[$i]]++;
$end3 = microtime(true);

$start4 = microtime(true);
foreach($aHash as &$val) $val++;
$end4 = microtime(true);

echo "foreach ".($end1 - $start1)."\n"; //foreach 0.947947025299
echo "while ".($end2 - $start2)."\n"; //while 0.847212076187
echo "for ".($end3 - $start3)."\n"; //for 0.439476966858
echo "foreach ref ".($end4 - $start4)."\n"; //foreach ref 0.0886030197144

//For these tests we MUST do an array lookup,
//since that is normally the *point* of iteration
//i'm also calling noop on it so that PHP doesn't
//optimize out the loopup.
function noop( $value ) {}

//Create an array of increasing indexes, w/ random values
$bHash = range( 0, 999999 );
shuffle( $bHash );

$bstart1 = microtime(true);
for($i = 0; $i < 1000000; ++$i) noop( $bHash[$i] );
$bend1 = microtime(true);

$bstart2 = microtime(true);
$i = 0; while($i < 1000000) { noop( $bHash[$i] ); ++$i; }
$bend2 = microtime(true);


$bstart3 = microtime(true);
foreach( $bHash as $value ) { noop( $value ); }
$bend3 = microtime(true);

echo "for ".($bend1 - $bstart1)."\n"; //for 0.397135972977
echo "while ".($bend2 - $bstart2)."\n"; //while 0.364789962769
echo "foreach ".($bend3 - $bstart3)."\n"; //foreach 0.346374034882

3

এটি 2020 এবং স্টাফগুলি পিএইচপি 7.4 এবং অপক্যাচে ব্যাপকভাবে বিকশিত হয়েছিল

ইপি এবং এইচটিএমএল অংশগুলি ছাড়াই এখানে ওপি ^ বেঞ্চমার্কটি ইউনিক্স সিএলআই হিসাবে চলেছে ।

নিয়মিত কম্পিউটারে স্থানীয়ভাবে পরীক্ষা চালানো হয়েছিল।

php -v

PHP 7.4.6 (cli) (built: May 14 2020 10:02:44) ( NTS )

পরিবর্তিত বেঞ্চমার্ক স্ক্রিপ্ট:

<?php 
 ## preperations; just a simple environment state

  $test_iterations = 100;
  $test_arr_size = 1000;

  // a shared function that makes use of the loop; this should
  // ensure no funny business is happening to fool the test
  function test($input)
  {
    //echo '<!-- '.trim($input).' -->';
  }

  // for each test we create a array this should avoid any of the
  // arrays internal representation or optimizations from getting
  // in the way.

  // normal array
  $test_arr1 = array();
  $test_arr2 = array();
  $test_arr3 = array();
  // hash tables
  $test_arr4 = array();
  $test_arr5 = array();

  for ($i = 0; $i < $test_arr_size; ++$i)
  {
    mt_srand();
    $hash = md5(mt_rand());
    $key = substr($hash, 0, 5).$i;

    $test_arr1[$i] = $test_arr2[$i] = $test_arr3[$i] = $test_arr4[$key] = $test_arr5[$key]
      = $hash;
  }

  ## foreach

  $start = microtime(true);
  for ($j = 0; $j < $test_iterations; ++$j)
  {
    foreach ($test_arr1 as $k => $v)
    {
      test($v);
    }
  }
  echo 'foreach '.(microtime(true) - $start)."\n";  

  ## foreach (using reference)

  $start = microtime(true);
  for ($j = 0; $j < $test_iterations; ++$j)
  {
    foreach ($test_arr2 as &$value)
    {
      test($value);
    }
  }
  echo 'foreach (using reference) '.(microtime(true) - $start)."\n";

  ## for

  $start = microtime(true);
  for ($j = 0; $j < $test_iterations; ++$j)
  {
    $size = count($test_arr3);
    for ($i = 0; $i < $size; ++$i)
    {
      test($test_arr3[$i]);
    }
  }
  echo 'for '.(microtime(true) - $start)."\n";  

  ## foreach (hash table)

  $start = microtime(true);
  for ($j = 0; $j < $test_iterations; ++$j)
  {
    foreach ($test_arr4 as $k => $v)
    {
      test($v);
    }
  }
  echo 'foreach (hash table) '.(microtime(true) - $start)."\n";

  ## for (hash table)

  $start = microtime(true);
  for ($j = 0; $j < $test_iterations; ++$j)
  {
    $keys = array_keys($test_arr5);
    $size = sizeOf($test_arr5);
    for ($i = 0; $i < $size; ++$i)
    {
      test($test_arr5[$keys[$i]]);
    }
  }
  echo 'for (hash table) '.(microtime(true) - $start)."\n";

আউটপুট:

foreach 0.0032877922058105
foreach (using reference) 0.0029420852661133
for 0.0025191307067871
foreach (hash table) 0.0035080909729004
for (hash table) 0.0061779022216797

আপনি দেখতে পাচ্ছেন যে বিবর্তনটি উন্মাদ, 2012 সালের রিপোর্টের চেয়ে প্রায় 560 সময় দ্রুত

আমার মেশিন এবং সার্ভারগুলিতে, আমার অসংখ্য পরীক্ষাগুলি অনুসরণ করে, লুপগুলির জন্য বেসিকগুলি দ্রুততম। এটি নেস্টেড লুপগুলি ব্যবহার করে আরও পরিষ্কার ( $ i $ j $ k ..)

এটি ব্যবহারে সর্বাধিক নমনীয় এবং আমার দৃষ্টিকোণ থেকে আরও ভাল পাঠযোগ্যতা রয়েছে।


0

আমি মনে করি তবে আমি নিশ্চিত নই: forমানগুলি পরীক্ষা এবং বৃদ্ধি করার জন্য লুপটি দুটি ক্রিয়াকলাপ গ্রহণ করে। foreachমেমরিতে ডেটা লোড করে তা প্রতিটি মানকে পুনরাবৃত্তি করবে।


7
সবার মতামত রয়েছে, লোকেরা উত্তর খুঁজতে স্ট্যাক ওভারফ্লোতে আসে। আপনি কী বলেছেন সে সম্পর্কে আপনি যদি নিশ্চিত না হন তবে উত্স কোড, ডকুমেন্টেশন, একটি গুগল অনুসন্ধান ইত্যাদি পরীক্ষা করুন
সেবাস্তিয়ান এফ।

যেহেতু পারফরম্যান্স গবেষণা এবং পরীক্ষার উপর ভিত্তি করে আপনার কিছু প্রমাণ সহ প্রকাশ করা উচিত। অনুগ্রহ করে আপনার রেফারেন্সগুলি সেই অনুযায়ী সরবরাহ করুন। আশা করি আপনি আপনার উত্তরটি উন্নত করতে পারেন।
মারওয়ান সেলিম

আমি মনে করি এটি সার্ভারের প্রকৃত লোড এবং আপনি লুপে কী করতে চান তার উপরও নির্ভর করে। আমি মনে করি এটি সার্ভারের প্রকৃত লোড এবং আপনি লুপে কী করতে চান তার উপরও নির্ভর করে। আমি জানতে চেয়েছিলাম যে সংখ্যাযুক্ত অ্যারের উপর পুনরাবৃত্তি করা আমার আরও ভালভাবে একটি ভবিষ্যদ্বাণী - বা লুপের জন্য ব্যবহার করা উচিত, তাই আমি পিএইচপি 7.4 সহ স্যান্ডবক্স.অনলাইনপ্পফানকশনস.কম এ একটি বেঞ্চমার্ক চালিয়েছি । আমি একই স্ক্রিপ্টকে বহুবার বারবার চালিত করি এবং প্রতিটি রানই আমাকে আলাদা ফলাফল দেয়। এক সময় ফর-লুপটি দ্রুত ছিল অন্য সময় ফরচ-লুপ এবং অন্য সময় তারা সমান ছিল।
আলেকজান্ডার বেহলিং
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.