পিএইচপি ফাংশনগুলির জন্য বিগ-ও-এর তালিকা


345

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

//very slow for large $prime_array
$prime_array = array( 2, 3, 5, 7, 11, 13, .... 104729, ... );
$result_array = array();
foreach( $prime_array => $number ) {
    $result_array[$number] = in_array( $number, $large_prime_array );
}

//speed is much less dependent on size of $prime_array, and runs much faster.
$prime_array => array( 2 => NULL, 3 => NULL, 5 => NULL, 7 => NULL,
                       11 => NULL, 13 => NULL, .... 104729 => NULL, ... );
foreach( $prime_array => $number ) {
    $result_array[$number] = array_key_exists( $number, $large_prime_array );
}

এটি কারণ in_arrayএকটি লিনিয়ার অনুসন্ধান ও (এন) দিয়ে প্রয়োগ করা হয়েছে যা বাড়ার সাথে সাথে রৈখিকভাবে ধীর $prime_arrayহয়ে যাবে। যেখানে array_key_existsফাংশনটি হ্যাশ লুकिंग ও (1) দিয়ে কার্যকর করা হয় যা হ্যাশ টেবিলটি অত্যন্ত জনবহুল না হওয়া পর্যন্ত ধীরে ধীরে চলবে না (এই ক্ষেত্রে এটি কেবল ও (এন))।

এখনও অবধি আমাকে ট্রায়াল এবং ত্রুটির মাধ্যমে বিগ-ও আবিষ্কার করতে হয়েছিল এবং মাঝেমধ্যে উত্স কোডটি দেখেছি । এখন প্রশ্নের ...

সমস্ত * অন্তর্নির্মিত পিএইচপি ফাংশনগুলির জন্য তাত্ত্বিক (বা ব্যবহারিক) বড় ও সময়ের একটি তালিকা আছে?

* বা কমপক্ষে আকর্ষণীয়

উদাহরণস্বরূপ, আমি তালিকাভুক্ত ফাংশন বড় হে ভবিষ্যদ্বাণী করা এটা খুঁজে খুব কঠিন কারণ সম্ভব বাস্তবায়ন পিএইচপি অজানা কোর ডাটা স্ট্রাকচার নির্ভর করে: array_merge, array_merge_recursive, array_reverse, array_intersect, array_combine, str_replace(অ্যারে ইনপুট সঙ্গে), ইত্যাদি


31
সম্পূর্ণ বিষয়বস্তু বন্ধ কিন্তু, 1 প্রধান নয়।
জেসন পুনিউন

24
পিএইচপি-তে অ্যারে হ্যাশটেবল। এটি আপনাকে জানার জন্য প্রয়োজনীয় সমস্ত কিছু বলা উচিত। হ্যাশ টেবিলের চাবিটি অনুসন্ধান করা হ'ল ও (1)। মানটির সন্ধান করা হ'ল ও (এন) - যা আপনি একটি অনিবৃদ্ধ সেটটিতে পরাজিত করতে পারবেন না। আপনার সম্পর্কে কৌতূহলের বেশিরভাগ ফাংশন সম্ভবত ও (এন)। অবশ্যই, যদি আপনি সত্যিই জানতে চান তবে আপনি উত্সটি পড়তে পারেন: cvs.php.net/viewvc.cgi/php-src/ext/standard/…
ফ্র্যাঙ্ক ফার্মার

11
রেকর্ডের জন্য, আপনি যা করতে চেষ্টা করছেন তার দ্রুত প্রয়োগকরণ (আপনার মানগুলির জন্য NULL ব্যবহার না করে) ব্যবহার trueএবং তারপরে উপস্থিতি ব্যবহারের জন্য পরীক্ষা করা হবে isset($large_prime_array[$number])। যদি আমি সঠিকভাবে মনে রাখি তবে এটি in_arrayক্রিয়াকলাপের চেয়ে কয়েকগুণ দ্রুত গতিযুক্ত।
ম্যাটবস্টা

3
বিগ হে নোটেশন গতি সম্পর্কে নয়। এটি আচরণ সীমাবদ্ধ করার বিষয়ে।
গম্বো

3
@ কেন্ডাল আমি তুলনা করছি না array_key_exists, আমি তুলনা করছি in_arrayin_arrayঅ্যারেতে প্রতিটি আইটেম পুনরাবৃত্তি করে এবং সূঁচের সাথে মানটি তুলনা করে যা আপনি এটি পাস করেন। যদি আপনি কীগুলিতে মানগুলি ফ্লিপ করেন (এবং কেবলমাত্র প্রতিটি মানকে একটি ডামি মানের সাথে প্রতিস্থাপন trueকরে issetযেমন ব্যবহার করা বহুগুণ দ্রুত হয় This এটি কারণ অ্যারের কীগুলি পিএইচপি দ্বারা সূচিত হয় (হ্যাশটেবলের মতো) quently ফলস্বরূপ, অনুসন্ধান এই পদ্ধতিতে একটি অ্যারে গতিতে উল্লেখযোগ্য উন্নতি করতে পারে
ম্যাটবস্টা

উত্তর:


649

যেহেতু মনে হচ্ছে না যে কেউ এই কাজ করেছে বলে মনে হচ্ছে না কোথাও রেফারেন্সের জন্য এটি রাখাই ভাল ধারণা। আমি যদিও এবং হয় বেঞ্চমার্ক বা কোড-স্কিমিংয়ের মাধ্যমে এর বৈশিষ্ট্যটি চিহ্নিত করতে পেরেছিarray_* ফাংশনগুলিকে । আমি আরও আকর্ষণীয় বিগ-ওটিকে শীর্ষে রাখার চেষ্টা করেছি। এই তালিকা সম্পূর্ণ নয়।

দ্রষ্টব্য: সমস্ত বিগ-ও যেখানে সত্যই ও (এন) হওয়া সত্ত্বেও একটি হ্যাশ লুকওয়্যার অনুমান করে গণনা করা হয় ও (1)। এন এর সহগ এত কম, একটি বিশাল যথেষ্ট অ্যারের সংরক্ষণের রাম ওভারহেড বিগ-ও দেখার বৈশিষ্ট্যগুলি কার্যকর হওয়া শুরু করার আগে আপনাকে আঘাত করবে। উদাহরণস্বরূপ একটি কল করার মধ্যে পার্থক্যarray_key_exists N = 1 এবং N = 1000,000 এ হ'ল 50% সময় বৃদ্ধি।

আকর্ষণীয় পয়েন্ট :

  1. isset/ array_key_existsহয় অনেক দ্রুত তুলনায় in_arrayএবংarray_search
  2. +(ইউনিয়ন) এর চেয়ে কিছুটা দ্রুত array_merge(এবং আরও সুন্দর দেখাচ্ছে)। তবে এটি ভিন্নভাবে কাজ করে তাই মনে রাখবেন।
  3. shuffle একই বিগ-ওয়ার স্তরে রয়েছে array_rand
  4. array_pop/ পুনরায় সূচক জরিমানার কারণে / এর array_pushচেয়ে দ্রুতarray_shiftarray_unshift

চেহারা :

array_key_existsও (এন) তবে ও (১) এর খুব কাছাকাছি - এটি সংঘর্ষে লিনিয়ার পোলিংয়ের কারণে, তবে সংঘর্ষের সম্ভাবনা খুব কম হওয়ায়, সহগও খুব ছোট। আরও বাস্তবসম্মত বিগ-ও দেওয়ার জন্য আমি আপনাকে হ্যাশ লুকআপকে ও (1) হিসাবে বিবেচনা করি। উদাহরণস্বরূপ N = 1000 এবং N = 100000 এর মধ্যে পার্থক্য কেবল প্রায় 50% ধীর হয়ে যায়।

isset( $array[$index] )O (n) তবে সত্যই ও (1) এর কাছাকাছি - এটি অ্যারে_কি_এক্সজিস্টগুলির মতো একই চেহারা ব্যবহার করে। যেহেতু এটি ভাষাটি নির্মাণ করছে, কীটি হার্ডকোড করা থাকলে লুকাকে ক্যাশে করবে, ফলে একই কীটি বারবার ব্যবহৃত হয় এমন ক্ষেত্রে গতি বাড়বে।

in_array ও (এন) - এটি কারণ এটি এটির সন্ধান করে যদিও এটির সন্ধান করে না until

array_search ও (এন) - এটি ইন_আরয়ের মতো একই মূল ফাংশনটি ব্যবহার করে তবে মান ফেরত দেয়।

সারি কার্য :

array_push ও (∑ var_i, সবার জন্য)

array_pop হে (1)

array_shift ও (এন) - এটিতে সমস্ত কীগুলি পুনর্নির্মাণ করতে হবে

array_unshift O (n + ∑ var_i, সকলের জন্য) - এটিতে সমস্ত কীগুলি পুনর্নির্মাণ করতে হবে

অ্যারে ছেদ, ইউনিয়ন, বিয়োগ :

array_intersect_key যদি ছেদ করা হয় 100% হে (সর্বোচ্চ (প্যারাম_আই_সাইজ) * ∑param_i_count, সকলের জন্য), যদি ছেদ হয় 0% ছেদ করে O (∑param_i_size, সকলের জন্য)

array_intersect ছেদ যদি 100% করে O (n ^ 2 * ∑param_i_count, সকলের জন্য), ছেদ যদি 0% ছেদ করে O (n ^ 2)

array_intersect_assoc যদি ছেদ করা হয় 100% হে (সর্বোচ্চ (প্যারাম_আই_সাইজ) * ∑param_i_count, সকলের জন্য), যদি ছেদ হয় 0% ছেদ করে O (∑param_i_size, সকলের জন্য)

array_diff ও (π প্যারাম_আই_ সাইজ, সকলের জন্য) - এটি সমস্ত প্যারাম_ আকারের পণ্য

array_diff_key O (∑ param_i_size, i এর জন্য! = 1) - এটি কারণ আমাদের প্রথম অ্যারেতে পুনরাবৃত্তি করার প্রয়োজন নেই।

array_merge ও (ray অ্যারে_আই, আই! = 1) - প্রথম অ্যারেতে পুনরাবৃত্তি করার প্রয়োজন নেই

+ (ইউনিয়ন) ও (এন), যেখানে এন ২ য় অ্যারের আকার (যেমন অ্যারে_ফার্স্ট + অ্যারে_সেকেন্ড) - অ্যারে_ড্র্যামের চেয়ে কম ওভারহেড যেহেতু এটি পুনর্নবীকরণ করতে হবে না

array_replace ও (∑ অ্যারে_আই, সবার জন্য)

এলোমেলো :

shuffle চালু)

array_rand ও (এন) - রৈখিক পোলের প্রয়োজন।

স্পষ্টত বিগ-ও :

array_fill চালু)

array_fill_keys চালু)

range চালু)

array_splice ও (অফসেট + দৈর্ঘ্য)

array_slice ও (অফসেট + দৈর্ঘ্য) বা ও (এন) দৈর্ঘ্য = ন্যূনাল হলে

array_keys চালু)

array_values চালু)

array_reverse চালু)

array_pad হে (pad_size)

array_flip চালু)

array_sum চালু)

array_product চালু)

array_reduce চালু)

array_filter চালু)

array_map চালু)

array_chunk চালু)

array_combine চালু)

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

সম্পাদনা করুন:

যারা পিএইচপি অ্যারে লুকআপগুলি সন্দেহ করেন তাদের পক্ষে O(N), আমি এটি পরীক্ষা করার জন্য একটি মানদণ্ড লিখেছি (তারা এখনও O(1)বেশিরভাগ বাস্তববাদী মানের জন্য কার্যকরভাবে রয়েছে ))

পিএইচপি অ্যারের লক গ্রাফ

$tests = 1000000;
$max = 5000001;


for( $i = 1; $i <= $max; $i += 10000 ) {
    //create lookup array
    $array = array_fill( 0, $i, NULL );

    //build test indexes
    $test_indexes = array();
    for( $j = 0; $j < $tests; $j++ ) {
        $test_indexes[] = rand( 0, $i-1 );
    }

    //benchmark array lookups
    $start = microtime( TRUE );
    foreach( $test_indexes as $test_index ) {
        $value = $array[ $test_index ];
        unset( $value );
    }
    $stop = microtime( TRUE );
    unset( $array, $test_indexes, $test_index );

    printf( "%d,%1.15f\n", $i, $stop - $start ); //time per 1mil lookups
    unset( $stop, $start );
}

5
@ কেন্ডল: ধন্যবাদ! আমি কিছুটা পড়া করেছি এবং এটি পিএইচপি সংঘর্ষের জন্য 'নেস্টেড' হ্যাশ টেবিল ব্যবহার করে turns এটি, সংঘর্ষের জন্য লগন কাঠামোর পরিবর্তে এটি অন্য একটি হ্যাশটেবল ব্যবহার করে। এবং আমি বুঝতে পারি যে কার্যত পিএইচপি হ্যাশ টেবিলগুলি ও (1) পারফরম্যান্স দেয়, বা কমপক্ষে কমপক্ষে ও (1) - হ্যাশ টেবিলের জন্য এটি। আমি কেবল কৌতূহলী ছিলাম যে আপনি কেন বলেছেন যে তারা "সত্যই ও (এন)" এবং "সত্যই ও (লগন)" নয়। যাই হোক, এটা দারুন পোস্ট!
ক্যাম

10
সময় সংক্রান্ত জটিলতাগুলি ডকুমেন্টেশনের সাথে অন্তর্ভুক্ত করা উচিত! সঠিক ফাংশনটি নির্বাচন করা আপনাকে এত বেশি সময় বাঁচাতে পারে, বা আপনি যা পরিকল্পনা করেছিলেন তা না করার জন্য বলতে পারেন: ইতিমধ্যে এই তালিকার জন্য ধন্যবাদ!
স্যামুয়েল

41
আমি জানি এই পুরানো ... তবে কি? এই বক্ররেখার মধ্যে ও (এন) মোটেও দেখা যায় না, এটি ও (লগ এন), এন.ইউইকিপিডিয়া . org / উইকি / লোগারিদম দেখায় । যা নেস্টেড হ্যাশ-ম্যাপের জন্য আপনি কী আশা করবেন তার সাথেও সঠিক।
Andreas

5
একটি অ্যারের উপাদানের উপর আনসেট করা বিগ-ও কী?
চন্দ্রু

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

5

আপনি সুনির্দিষ্টভাবে বর্ণিত মামলার ব্যাখ্যাটি হ'ল সংযুক্তিযুক্ত অ্যারেগুলি হ্যাশ টেবিল হিসাবে প্রয়োগ করা হয় - সুতরাং কী দ্বারা অনুসন্ধান করা (এবং অনুরূপভাবে, array_key_exists ) হ'ল হ'ল (1)। যাইহোক, অ্যারেগুলি মান অনুসারে সূচিত হয় না, সুতরাং অ্যারেতে একটি মান বিদ্যমান কিনা তা আবিষ্কারের সাধারণ ক্ষেত্রে একমাত্র উপায় লিনিয়ার অনুসন্ধান। সেখানে অবাক হওয়ার কিছু নেই।

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


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

@ কেন্ডাল আমি উত্স কোডে ডাইভিংয়ের বিষয়ে আপনার উল্লেখটি উপেক্ষা করেছি। তবে, আমার উত্তরে একটি উত্তর রয়েছে: "আমি মনে করি না পিএইচপি পদ্ধতিগুলির অ্যালগরিদমিক জটিলতার নির্দিষ্ট বিস্তৃত ডকুমেন্টেশন রয়েছে।" "না" একটি পুরোপুরি বৈধ উত্তর। (সি:
দথান

4

আপনি প্রায় সর্বদা issetপরিবর্তে ব্যবহার করতে চান array_key_exists। আমি ইন্টার্নালগুলির দিকে নজর দিচ্ছি না, তবে আমি নিশ্চিত যে array_key_existsও (এন) হ'ল কারণ এটি অ্যারের প্রতিটি কী ধরে পুনরাবৃত্তি করে, যখন issetআপনি অ্যাক্সেস করার সময় একই হ্যাশ অ্যালগরিদম ব্যবহার করে উপাদানটি অ্যাক্সেস করার চেষ্টা করেন একটি অ্যারে সূচক। এটি ও (1) হওয়া উচিত।

নজর রাখার জন্য একটি "গোছা" হ'ল:

$search_array = array('first' => null, 'second' => 4);

// returns false
isset($search_array['first']);

// returns true
array_key_exists('first', $search_array);

আমি কৌতূহলী ছিলাম, তাই আমি পার্থক্যটি চিহ্নিত করলাম:

<?php

$bigArray = range(1,100000);

$iterations = 1000000;
$start = microtime(true);
while ($iterations--)
{
    isset($bigArray[50000]);
}

echo 'is_set:', microtime(true) - $start, ' seconds', '<br>';

$iterations = 1000000;
$start = microtime(true);
while ($iterations--)
{
    array_key_exists(50000, $bigArray);
}

echo 'array_key_exists:', microtime(true) - $start, ' seconds';
?>

is_set:0.132308959961 সেকেন্ড
array_key_exists:2.33202195168 সেকেন্ড

অবশ্যই এটি সময়ের জটিলতা প্রদর্শন করে না, তবে এটি দেখায় যে 2 টি কার্য কীভাবে একে অপরের সাথে তুলনা করে।

সময়ের জটিলতার জন্য পরীক্ষা করতে, প্রথম কী এবং শেষ কীতে এই ফাংশনগুলির একটি চালাতে যে পরিমাণ সময় লাগে তার সাথে তুলনা করুন।


9
এটা ভুল. আমি নিশ্চিত 100% নিশ্চিত অ্যারে_কি_এক্সিজিস্টগুলিকে প্রতিটি কীতে পুনরাবৃত্তি করতে হবে না। আপনি যদি বিশ্বাস না করেন তবে নীচের লিঙ্কটি একবার দেখুন। ইসেটটি এত দ্রুত হওয়ার কারণ এটি একটি ভাষা নির্মাণ। যার অর্থ এটি একটি ফাংশন কল করার ওভারহেড নেই। এছাড়াও, আমি মনে করি এটি সম্ভবত এটি লুকিয়ে রাখছে। এছাড়াও, এটি প্রশ্নের উত্তর নয়! আমি পিএইচপি ফাংশনগুলির জন্য বিগ (ও) এর একটি তালিকা চাই (যেমন প্রশ্নের উত্তর রয়েছে)। আমার উদাহরণগুলির একক মানদণ্ড নয়। svn.php.net/repository/php/php-src/branches/PHP_5_3/ext/…
কেন্ডল হপকিন্স

আপনি যদি এখনও আমাকে বিশ্বাস না করেন তবে আমি বিষয়টিটি প্রদর্শনের জন্য একটি ছোট মানদণ্ড তৈরি করেছি। পেস্টবিন.com
কেন্ডল হপকিন্স

আপনার বেঞ্চমার্কে যা ভুল তা হ'ল আপনাকে xdebug অক্ষম করতে হবে। =)
গিলহার্ম ব্লাঙ্কো

3
আপনি অ্যারে_কি_এক্সেস্টের ওপরে ইসসেটটি ব্যবহার করতে চান তার দুটি সমালোচনামূলক কারণ রয়েছে। প্রথমত, আইসেট হ'ল ফাংশন কলের ব্যয় হ্রাস করার জন্য একটি ভাষা নির্মাণ। এটি $arrray[] = $appendবনাম array_push($array, $append)যুক্তির অনুরূপ । দ্বিতীয়ত, অ্যারে_কি_এক্সজিস্টগুলি অ-সেট এবং নাল মানগুলির মধ্যেও পার্থক্য করে। জন্য $a = array('fred' => null); array_key_exists('fred', $a)ফিরে আসবে সত্য যখন isset($['fred'])মিথ্যা ফিরে আসবে। এই অতিরিক্ত পদক্ষেপটি তুচ্ছ-তুচ্ছ নয় এবং কার্যকর করার সময়টি বাড়িয়ে তোলে।
orca

0

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

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