লুপিংয়ের চেয়ে পুনরাবৃত্তি কি কখনও দ্রুত?


286

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

আমি যা জিজ্ঞাসা করছি তা হল লুপের চেয়ে পুনরাবৃত্তি কি কখনও দ্রুত? আমার কাছে মনে হচ্ছে, আপনি সর্বদা একটি লুপটি সংশোধন করতে সক্ষম হন এবং এটি পুনরাবৃত্ত ক্রিয়াকলাপের চেয়ে আরও দ্রুত সম্পাদন করতে সক্ষম হন কারণ লুপটি অনুপস্থিত থাকে প্রতিনিয়ত নতুন স্ট্যাক ফ্রেম স্থাপন করে।

আমি বিশেষত সন্ধান করছি যে অ্যাপ্লিকেশনগুলিতে পুনরাবৃত্তি দ্রুত হয় কিনা যেখানে ডেটা হ্যান্ডেল করার জন্য পুনরাবৃত্তি হ'ল সঠিক উপায়, যেমন বাইনারি গাছগুলিতে কিছু সাজানোর কাজ ইত্যাদি etc.


3
কখনও কখনও পুনরাবৃত্তির পদ্ধতি বা কিছু পুনরাবৃত্তির জন্য ক্লোজড ফর্মুলাগুলি পরিণত হতে কয়েক শতাব্দী সময় নেয়। আমি মনে করি কেবল সেই সময়েই পুনরাবৃত্তি দ্রুত হয় :) lol
প্রতীক দেওঘরে

24
নিজের পক্ষে কথা বলছি, আমি অনেক বেশি পুনরাবৃত্তি পছন্দ করি। ;-)
ইট্রেটর



@ প্রকটিক দেওগরে না, প্রশ্নটি সম্পূর্ণ ভিন্ন অ্যালগরিদম বেছে নেওয়ার বিষয়ে নয়। আপনি সর্বদা একটি পুনরাবৃত্ত ফাংশনকে লুপ ব্যবহার করে এমন একটি কার্যকর পদ্ধতিতে রূপান্তর করতে পারেন। উদাহরণস্বরূপ, এই উত্তরের পুনরাবৃত্ত এবং লুপিং উভয় ফর্ম্যাটে একই অ্যালগরিদম রয়েছে । সাধারণভাবে, আপনি পুনরাবৃত্ত ফাংশনটিতে একটি আর্গুমেন্ট একটি স্ট্যাকের মধ্যে রাখবেন, কলটি স্ট্যাকের দিকে ঠেলে, ফাংশন থেকে ফিরে স্ট্যাক থেকে প্রত্যাখ্যান করে।
TamaMcGlinn

উত্তর:


357

এটি নির্ভরযোগ্য ভাষার উপর নির্ভর করে। আপনি 'ভাষা-অজ্ঞেয়বাদী' লিখেছেন, তাই আমি কয়েকটি উদাহরণ দেব।

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

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

আমি জানি যে কিছু স্কিম বাস্তবায়নে, পুনরাবৃত্তি সাধারণত লুপিংয়ের চেয়ে দ্রুত হবে।

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

সংযোজন: কিছু পরিবেশে, সর্বোত্তম বিকল্পটি পুনরাবৃত্তি বা পুনরাবৃত্তি নয় বরং এর পরিবর্তে উচ্চতর ক্রমের কাজ। এর মধ্যে রয়েছে "মানচিত্র", "ফিল্টার" এবং "হ্রাস" (যা "ভাঁজ" নামেও পরিচিত)। এইগুলি কেবল পছন্দসই স্টাইলই নয়, কেবল প্রায়শই ক্লিনার নয়, কিছু পরিবেশে এই ফাংশনগুলি স্বয়ংক্রিয়ভাবে সমান্তরালকরণ থেকে উত্সাহ প্রাপ্ত প্রথম (বা কেবল) - যাতে এগুলি পুনরাবৃত্তি বা পুনরাবৃত্তিগুলির তুলনায় উল্লেখযোগ্যভাবে দ্রুততর হতে পারে। ডেটা সমান্তরাল হাস্কেল এমন পরিবেশের উদাহরণ।

তালিকার বোধগম্যতা অন্য বিকল্প, তবে এগুলি সাধারণত পুনরাবৃত্তি, পুনরাবৃত্তি বা উচ্চতর ক্রমের ক্রিয়াকলাপের জন্য কেবল সিনট্যাকটিক চিনি।


48
আমি এটি +1 করেছি এবং মন্তব্য করতে চাই যে "পুনরাবৃত্তি" এবং "লুপগুলি" কেবল মানুষ তাদের কোডের নাম দেয়। পারফরম্যান্সের জন্য গুরুত্বপূর্ণ বিষয়গুলি কীভাবে আপনি জিনিসগুলির নাম রাখেন তা নয় , বরং সেগুলি কীভাবে সংকলিত / ব্যাখ্যা করা হয়। সংজ্ঞা অনুসারে পুনরাবৃত্তি একটি গাণিতিক ধারণা, এবং স্ট্যাক ফ্রেম এবং সমাবেশ স্টাফগুলির সাথে খুব কম সম্পর্ক রাখে।
পি শোভিত

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

4
সাধারণত পুনরাবৃত্তিগুলি লুপগুলিতে সংকলিত হয়, লুপগুলি নিম্ন স্তরের কনস্ট্রাক্ট থাকে। কেন? কারণ পুনরাবৃত্তি সাধারণত কিছু ডেটা কাঠামোর উপর প্রতিষ্ঠিত হয়, একটি প্রাথমিক এফ-বীজগণিতকে প্ররোচিত করে এবং আপনাকে (পুনরাবৃত্ত) গণনার কাঠামো সম্পর্কে প্ররোচিত যুক্তি সহ সমাপ্তি সম্পর্কে কিছু বৈশিষ্ট্য প্রমাণ করার অনুমতি দেয়। যে প্রক্রিয়াটির মাধ্যমে পুনরাবৃত্তিগুলি লুপগুলিতে সংকলিত হয় তা হ'ল লেজ কল অপ্টিমাইজেশন।
ক্রিস্টোফার মিকিনস্কি

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

53

পুনরাবৃত্তি একটি লুপ চেয়ে কখনও দ্রুত হয়?

না, আইট্রেশন সবসময় পুনরাবৃত্তির চেয়ে দ্রুত হবে। (একটি ভন নিউমান আর্কিটেকচারে)

ব্যাখ্যা:

আপনি যদি স্ক্র্যাচ থেকে জেনেরিক কম্পিউটারের ন্যূনতম অপারেশনগুলি তৈরি করেন তবে "আইট্রেশন" বিল্ডিং ব্লক হিসাবে প্রথমে আসে এবং "পুনরাবৃত্তি" এর চেয়ে কম সংস্থানীয় সংস্থান হয়, এরগো দ্রুত হয়।

স্ক্র্যাচ থেকে সিউডো-কম্পিউটিং-মেশিন তৈরি করা:

নিজেকে প্রশ্ন করুন : একটি অ্যালগরিদম অনুসরণ করতে এবং কোনও ফলাফলটিতে পৌঁছানোর জন্য আপনাকে কোনও মান গণনা করার দরকার কী ?

আমরা ধারণাগুলির একটি শ্রেণিবিন্যাস স্থাপন করব, স্ক্র্যাচ থেকে শুরু করে প্রথমে প্রাথমিক, মূল ধারণাগুলি সংজ্ঞায়িত করব, তারপরে সেগুলি সহ দ্বিতীয় স্তরের ধারণাগুলি তৈরি করব।

  1. প্রথম ধারণা: মেমরি সেল, স্টোরেজ, স্টেট । চূড়ান্ত এবং মধ্যবর্তী ফলাফলের মানগুলি সংরক্ষণ করার জন্য আপনার কিছু স্থানের প্রয়োজন । আসুন ধরে নেওয়া যাক আমাদের কাছে "পূর্ণসংখ্যা" কোষের একটি অসীম অ্যারে রয়েছে, যাকে মেমোরি , এম [0..ইসিমেন্ট] বলা হয়।

  2. নির্দেশাবলী: কিছু করুন - একটি ঘরে রূপান্তর করুন, এর মান পরিবর্তন করুন। পরিবর্তন রাষ্ট্র । প্রতিটি আকর্ষণীয় নির্দেশ একটি রূপান্তর সম্পাদন করে। প্রাথমিক নির্দেশাবলী হ'ল:

    ক) মেমরি সেলগুলি সেট এবং সরান

    • মেমরিতে একটি মান সঞ্চয় করুন, যেমন: 5 মি [4] স্টোর করুন
    • অন্য অবস্থানে একটি মান অনুলিপি করুন: উদা: স্টোর এম [4] মি [8]

    খ) যুক্তি এবং পাটিগণিত

    • এবং, বা, xor, না
    • যোগ, উপ, মুল, ডিভ উদাহরণস্বরূপ মি [7] মি [8] যোগ করুন
  3. একটি এক্সিকিউটিভ এজেন্ট : একটি আধুনিক সিপিইউতে একটি মূল । "এজেন্ট" এমন একটি জিনিস যা নির্দেশাবলী কার্যকর করতে পারে। একটি এজেন্ট এছাড়াও কাগজে অ্যালগরিদম নিম্নলিখিত একজন ব্যক্তির হতে পারে।

  4. পদক্ষেপের ক্রম: নির্দেশাবলীর ক্রম : যেমন: প্রথমে এটি করুন, পরে এটি করুন ইত্যাদি etc. নির্দেশিকাগুলির একটি আবশ্যিক ক্রম। এমনকি একটি লাইন এক্সপ্রেশন হ'ল "নির্দেশাবলীর একটি অপরিহার্য ধারা"। আপনার যদি একটি নির্দিষ্ট "মূল্যায়নের আদেশ" দিয়ে অভিব্যক্তি হয় তবে আপনার পদক্ষেপ রয়েছে । এর অর্থ এটি এমনকি একটি একক রচিত এক্সপ্রেশনটির অন্তর্নিহিত "পদক্ষেপ" রয়েছে এবং এতে অন্তর্নিহিত স্থানীয় পরিবর্তনশীল রয়েছে (আসুন একে "ফলাফল" বলি)। উদাহরণ:

    4 + 3 * 2 - 5
    (- (+ (* 3 2) 4 ) 5)
    (sub (add (mul 3 2) 4 ) 5)  
    

    উপরের অভিব্যক্তিটি অন্তর্ভুক্ত "ফলাফল" পরিবর্তনশীল সহ 3 টি পদক্ষেপ বোঝায়।

    // pseudocode
    
           1. result = (mul 3 2)
           2. result = (add 4 result)
           3. result = (sub result 5)
    

    সুতরাং এমনকি ইনফিক্স এক্সপ্রেশনও, যেহেতু আপনার মূল্যায়নের একটি নির্দিষ্ট ক্রম রয়েছে, তাই নির্দেশাবলীর একটি আবশ্যিক ক্রম । অভিব্যক্তিটি একটি নির্দিষ্ট ক্রমে তৈরি করা ক্রিয়াকলাপকে বোঝায় এবং পদক্ষেপ রয়েছে বলে একটি অন্তর্নিহিত "ফলাফল" অন্তর্বর্তী ভেরিয়েবলও রয়েছে।

  5. নির্দেশ পয়েন্টার : আপনার যদি পদক্ষেপগুলির ক্রম থাকে তবে আপনার একটি অন্তর্নিহিত "নির্দেশিকা নির্দেশক "ও রয়েছে। নির্দেশিকা নির্দেশক পরবর্তী নির্দেশকে চিহ্নিত করে এবং নির্দেশটি পড়ার পরে কিন্তু নির্দেশ কার্যকর করার আগে অগ্রসর হয়।

    এই সিউডো-কম্পিউটিং-মেশিনে, নির্দেশ পয়েন্টারটি মেমোরির অংশ । (দ্রষ্টব্য: সাধারণত নির্দেশ পয়েন্টারটি একটি সিপিইউ কোরের একটি "বিশেষ রেজিস্ট্রার" হবে, তবে এখানে আমরা ধারণাগুলি সহজ করব এবং সমস্ত ডেটা (নিবন্ধভুক্ত অন্তর্ভুক্ত) "মেমোরি" এর অংশ বলে ধরে নেব)

  6. ঝাঁপ দাও - একবার আপনার নির্দেশিত সংখ্যক পদক্ষেপ এবং নির্দেশ পয়েন্টার হয়ে গেলে আপনি নির্দেশ পয়েন্টারের নিজেই মান পরিবর্তন করতে " স্টোর " নির্দেশিকাটি প্রয়োগ করতে পারেন । আমরা স্টোর নির্দেশের এই নির্দিষ্ট ব্যবহারটিকে একটি নতুন নাম দিয়ে ডাকব : ঝাঁপ দাও । আমরা একটি নতুন নাম ব্যবহার করি কারণ এটি একটি নতুন ধারণা হিসাবে ভাবা সহজ। নির্দেশিকা নির্দেশকটি পরিবর্তন করে আমরা এজেন্টকে "ধাপে x এ যেতে" নির্দেশ দিচ্ছি।

  7. অসীম স্বরলিপি : পিছনে ঝাঁপ দিয়ে এখন আপনি এজেন্টকে কয়েকটি নির্দিষ্ট পদক্ষেপ "পুনরাবৃত্তি" করতে পারেন। এই সময়ে আমরা অসীম Iteration আছে।

                       1. mov 1000 m[30]
                       2. sub m[30] 1
                       3. jmp-to 2  // infinite loop
    
  8. শর্তসাপেক্ষ - নির্দেশাবলীর শর্তসাপেক্ষ কার্যকর। "শর্তসাপেক্ষ" ধারাটির সাহায্যে আপনি শর্তাধীন বর্তমান অবস্থার উপর ভিত্তি করে একাধিক নির্দেশের একটি কার্যকর করতে পারেন (যা পূর্ববর্তী নির্দেশের সাথে সেট করা যেতে পারে)।

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

    1. mov 1000 m[30]
    2. sub m[30] 1
    3. (if not-zero) jump 2  // jump only if the previous 
                            // sub instruction did not result in 0
    
    // this loop will be repeated 1000 times
    // here we have proper ***iteration***, a conditional loop.
    
  10. নামকরণ : নির্দিষ্ট মেমোরি অবস্থানের জন্য ডেটা ধরে রাখা বা একটি পদক্ষেপ রাখা নামকে দেওয়া । এটি কেবল একটি "সুবিধার্থে" থাকার জন্য। আমরা মেমরির অবস্থানগুলির জন্য "নামগুলি" সংজ্ঞায়িত করার ক্ষমতা রেখে কোনও নতুন নির্দেশনা যুক্ত করি না। "নামকরণ" এজেন্টের জন্য নির্দেশ নয়, এটি আমাদের কাছে কেবল একটি সুবিধা। নামকরণ কোডকে (এই মুহুর্তে) পড়া সহজ করে ও পরিবর্তন করা সহজ করে।

       #define counter m[30]   // name a memory location
       mov 1000 counter
    loop:                      // name a instruction pointer location
        sub counter 1
        (if not-zero) jmp-to loop  
    
  11. এক-স্তরের সাবরুটিন : ধরুন আপনার ঘন ঘন সঞ্চালনের জন্য প্রয়োজনীয় কয়েকটি পদক্ষেপ রয়েছে। আপনি পদক্ষেপগুলিকে মেমোরিতে একটি নামী অবস্থানে সংরক্ষণ করতে পারেন এবং তারপরে যখন আপনি তাদের (কল) কার্যকর করতে হবে তখন সেই অবস্থানে যেতে পারেন । ক্রম শেষে আপনি কার্যকর করতে চালিয়ে যাওয়ার জন্য কলিং পয়েন্টে ফিরে যেতে হবে । এই প্রক্রিয়াটির সাহায্যে আপনি মূল নির্দেশাবলী রচনা করে নতুন নির্দেশাবলী (সাবরুটাইনগুলি) তৈরি করছেন ।

    বাস্তবায়ন: (কোনও নতুন ধারণার প্রয়োজন নেই)

    • একটি পূর্বনির্ধারিত মেমরি অবস্থানে বর্তমান নির্দেশ পয়েন্টার সংরক্ষণ করুন
    • সাবরোটিনে ঝাঁপ দাও
    • সাবরুটাইন শেষে, আপনি পূর্বনির্ধারিত মেমরি অবস্থান থেকে নির্দেশিকা পয়েন্টারটি পুনরুদ্ধার করে কার্যকর কলটির নিম্নলিখিত নির্দেশে কার্যকরভাবে পিছনে ফিরে যান

    নিয়ে সমস্যা এক পর্যায়ের বাস্তবায়ন: আপনি একটি সাবরুটিন থেকে অন্য সাবরুটিন কল করতে পারবেন না। যদি আপনি তা করেন, আপনি ফেরত ঠিকানা (গ্লোবাল ভেরিয়েবল) ওভাররাইট করবেন, যাতে আপনি কল করতে পারবেন না।

    সাবউটাইনগুলির আরও ভাল বাস্তবায়ন করতে : আপনার একটি স্ট্যাক দরকার

  12. স্ট্যাক : আপনি একটি "স্ট্যাক" হিসাবে কাজ করার জন্য একটি মেমোরি স্পেস নির্ধারণ করেন, আপনি স্ট্যাকের উপর "ধাক্কা" দিতে পারেন, এবং শেষ "ধাক্কা" মানটিও "পপ" করতে পারেন। একটি স্ট্যাক বাস্তবায়নের জন্য আপনার একটি স্ট্যাক পয়েন্টার (নির্দেশ পয়েন্টারের অনুরূপ) প্রয়োজন হবে যা স্ট্যাকের প্রকৃত "মাথা" নির্দেশ করে। আপনি যখন কোনও মান "চাপ" দেন, তখন স্ট্যাক পয়েন্টারটি হ্রাস পায় এবং আপনি মানটি সঞ্চয় করেন। আপনি যখন "পপ" করেন, আপনি প্রকৃত স্ট্যাক পয়েন্টারটিতে মান পাবেন এবং তারপরে স্ট্যাক পয়েন্টারটি বাড়িয়ে তোলা হবে।

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

  14. পুনরাবৃত্তি : যখন সাবরুটিন নিজেকে কল করে তখন কী ঘটে ?. এটিকে "পুনরাবৃত্তি" বলা হয়।

    সমস্যা: স্থানীয় মধ্যবর্তী ফলাফলগুলিকে ওভাররাইটিং করা একটি সাববুটিন মেমরিতে সঞ্চয় করতে পারে। যেহেতু আপনি একই পদক্ষেপগুলি কল / পুনঃব্যবহার করছেন, যদি মধ্যবর্তী ফলাফলটি পূর্বনির্ধারিত মেমরি অবস্থানগুলিতে (গ্লোবাল ভেরিয়েবল) সঞ্চিত থাকে তবে সেগুলি নেস্টেড কলগুলিতে ওভাররাইট করা হবে।

    সমাধান: পুনরাবৃত্তির অনুমতি দেওয়ার জন্য, সাবরুটাইনগুলি স্থানীয় মধ্যবর্তী ফলাফলগুলি স্ট্যাকের মধ্যে সংরক্ষণ করতে হবে , সুতরাং, প্রতিটি পুনরাবৃত্তির কল (প্রত্যক্ষ বা অপ্রত্যক্ষ) মধ্যবর্তী ফলাফলগুলি বিভিন্ন মেমরির স্থানে সংরক্ষণ করা হয়।

...

পুনরাবৃত্তি পৌঁছে আমরা এখানে থামাতে।

উপসংহার:

ভন নিউম্যান আর্কিটেকচারে, স্পষ্টতই "আইট্রেশন" হ'ল "পুনরাবৃত্তি" এর চেয়ে সহজ / মৌলিক ধারণা We স্তরে আমাদের "আইট্রেশন" এর একটি রূপ রয়েছে , যখন "পুনরাবৃত্তি" ধারণার ক্রমবিন্যাসের 14 স্তরে রয়েছে।

মেশিনের কোডে আইট্রেশন সর্বদা দ্রুততর হবে কারণ এটি কম নির্দেশাবলী কম সিপিইউ চক্রকে বোঝায় lies

কোনটা ভালো"?

  • আপনি যখন সহজ, ক্রমানুসারে ডেটা স্ট্রাকচারগুলি প্রসেস করছেন তখন আপনার "পুনরাবৃত্তি" ব্যবহার করা উচিত এবং সর্বত্র একটি "সাধারণ লুপ" করবে will

  • আপনার যখন "পুনরাবৃত্তি" ব্যবহার করা উচিত যখন আপনার পুনরাবৃত্ত তথ্য কাঠামো প্রসেস করতে হবে (আমি তাদের "ফ্র্যাক্টাল ডেটা স্ট্রাকচার" বলতে চাই), বা যখন পুনরাবৃত্তির সমাধানটি আরও স্পষ্টভাবে "মার্জিত" হয়।

পরামর্শ : কাজের জন্য সর্বোত্তম সরঞ্জামটি ব্যবহার করুন, তবে বুদ্ধিমানের সাথে চয়ন করার জন্য প্রতিটি সরঞ্জামের অভ্যন্তরীণ কার্যকারিতাটি বুঝুন।

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


2
আপনি ধরে নিচ্ছেন যে আপনার অগ্রগতি 1) প্রয়োজনীয় এবং 2) এটি থমকে গেছে যেখানে আপনি করেছিলেন were তবে 1) এটি প্রয়োজনীয় নয় (উদাহরণস্বরূপ, পুনরাবৃত্তি একটি লাফে পরিণত হতে পারে, যেমন গৃহীত উত্তরটি ব্যাখ্যা করেছে, সুতরাং কোনও স্ট্যাকের প্রয়োজন নেই), এবং ২) এটি সেখানে থামতে হবে না (উদাহরণস্বরূপ, অবশেষে আপনি 'সমান্তরাল প্রক্রিয়াকরণে পৌঁছে যাব, যা আপনার দ্বিতীয় ধাপে প্রবর্তন করার সাথে সাথে আপনার পরিবর্তনযোগ্য অবস্থা থাকলে লকগুলির প্রয়োজন হতে পারে, তাই সমস্ত কিছুই ধীরে ধীরে হ্রাস পায়; যখন কোনও কার্যকরী / পুনরাবৃত্তের মতো অপরিবর্তনীয় সমাধান লকিং এড়ায়, তাই দ্রুত / আরও সমান্তরাল হতে পারে) ।
হামিজাইল ২ig

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

"সত্যই দরকারী পুনরাবৃত্তি একটি লাফ মধ্যে রূপান্তরিত করা যায় না" -> সুতরাং টেল কল অপ্টিমাইজেশন কোনভাবেই অকেজো? এছাড়াও, অপরিবর্তনীয় এবং পুনরাবৃত্তি অরথগোনাল হতে পারে তবে আপনি পরিবর্তনীয় কাউন্টারগুলির সাথে লুপিংটি করেন your আপনার পদক্ষেপটি 9 দেখুন me আমার কাছে মনে হয় আপনি লুপিং এবং পুনরাবৃত্তি মূলত পৃথক ধারণা বলে মনে করছেন; তারা না। stackoverflow.com/questions/2651112/...
hmijail শোক resignees

@hmijail আমি মনে করি যে "দরকারী" এর চেয়ে ভাল শব্দটি "সত্য" is টেল পুনরাবৃত্তি সত্য পুনরাবৃত্তি নয় কারণ এটি কেবল শর্তহীন শাখার ছদ্মবেশে অর্থাৎ পুনরাবৃত্তির ছদ্মবেশে ফাংশন কলিং সিনট্যাক্স ব্যবহার করে। সত্যিকারের পুনরাবৃত্তি আমাদের একটি ব্যাকট্র্যাকিং স্ট্যাক সরবরাহ করে। যাইহোক, লেজ পুনরাবৃত্তি এখনও অভিব্যক্তিপূর্ণ, যা এটি দরকারী করে তোলে। পুনরাবৃত্তির বৈশিষ্ট্য যা নির্ভুলতার জন্য কোড বিশ্লেষণ করা সহজ বা সহজ করে তোলে তা টেল কল ব্যবহার করে প্রকাশ করা হলে পুনরাবৃত্ত কোডে প্রদান করা হয়। যদিও এটি অতিরিক্ত প্যারামিটারগুলির মতো লেজ সংস্করণে অতিরিক্ত জটিলতায় কিছুটা সামান্য অফসেট হয়ে যায়।
কাজ

34

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

আমার একটি কেস হয়েছে যেখানে জাভাতে একটি পুনরাবৃত্ত আলগোরিদিম পুনরায় লেখার ফলে এটি ধীর হয়ে গেছে।

সুতরাং ডান পদ্ধতির প্রথমে এটি সবচেয়ে প্রাকৃতিক উপায়ে লিখতে হবে, কেবল প্রোফাইলিং যদি এটি গুরুত্বপূর্ণ হয় তবেই অনুকূলিতকরণ করুন, এবং তারপরে অনুমিত উন্নতিটি পরিমাপ করুন।


2
" প্রথমে এটি সবচেয়ে প্রাকৃতিক উপায়ে লিখুন " এর জন্য +1 এবং বিশেষত " শুধুমাত্র প্রোফাইলিং যদি এটি সমালোচনামূলক হয় তবেই অনুকূলিতকরণ করুন "
ট্রিপহাউন্ড

2
হার্ডওয়্যার স্ট্যাক ম্যানুয়ালি প্রয়োগ করা, ইন-হিপ স্ট্যাকের চেয়ে সফ্টওয়্যারের চেয়ে দ্রুত হতে পারে তা স্বীকার করার জন্য +1 কার্যকরভাবে দেখানো হচ্ছে যে সমস্ত "না" উত্তর ভুল।
sh1

12

লেজ পুনরাবৃত্তি লুপিং হিসাবে দ্রুত। অনেক কার্যকরী ভাষাগুলিতে তাদের মধ্যে লেজ পুনরাবৃত্তি প্রয়োগ করা হয়েছে।


35
লেজ পুনরাবৃত্তি লুপিংয়ের মতো দ্রুত হতে পারে , যখন একটি টেইল কল অপ্টিমাইজেশন প্রয়োগ করা হয়: c2.com/cgi/wiki? টেলকলাপ্পিমাইজেশন
জোচিম

12

প্রতিটি, পুনরাবৃত্তি এবং পুনরাবৃত্তির জন্য একেবারে কী করা উচিত তা বিবেচনা করুন।

  • পুনরাবৃত্তি: লুপের শুরুতে একটি লাফ
  • পুনরাবৃত্তি: ডাকা ফাংশন শুরুতে একটি লাফ

আপনি দেখতে পাচ্ছেন যে এখানে পার্থক্যের জন্য খুব বেশি জায়গা নেই।

(আমি ধরে নিই যে পুনরাবৃত্তি একটি টেল-কল এবং সংকলক যে অপটিমাইজেশন সম্পর্কে সচেতন রয়েছে)।


9

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

টিএল; ডিআর রিকার্সিভ অ্যালগরিদমগুলির সাধারণত পুনরাবৃত্ত লোকগুলির তুলনায় আরও খারাপ ক্যাশের আচরণ থাকে।


6

এখানে বেশিরভাগ উত্তর ভুল । সঠিক উত্তর এটি নির্ভর করে । উদাহরণস্বরূপ, এখানে দুটি সি ফাংশন রয়েছে যা গাছের মধ্য দিয়ে চলে। প্রথমে পুনরাবৃত্তিকারী:

static
void mm_scan_black(mm_rc *m, ptr p) {
    SET_COL(p, COL_BLACK);
    P_FOR_EACH_CHILD(p, {
        INC_RC(p_child);
        if (GET_COL(p_child) != COL_BLACK) {
            mm_scan_black(m, p_child);
        }
    });
}

এবং এখানে পুনরাবৃত্তি ব্যবহার করে একই ফাংশন প্রয়োগ করা হয়েছে:

static
void mm_scan_black(mm_rc *m, ptr p) {
    stack *st = m->black_stack;
    SET_COL(p, COL_BLACK);
    st_push(st, p);
    while (st->used != 0) {
        p = st_pop(st);
        P_FOR_EACH_CHILD(p, {
            INC_RC(p_child);
            if (GET_COL(p_child) != COL_BLACK) {
                SET_COL(p_child, COL_BLACK);
                st_push(st, p_child);
            }
        });
    }
}

কোডটির বিশদটি বোঝা গুরুত্বপূর্ণ নয়। কেবল এটি pনোড এবং P_FOR_EACH_CHILDএটি হাঁটাচলা করে। পুনরাবৃত্ত সংস্করণে আমাদের একটি স্পষ্ট স্ট্যাক প্রয়োজন stযার উপর নোডগুলি ধাক্কা দেওয়া হয় এবং তারপরে পপড এবং হেরফের হয় ulated

পুনরাবৃত্তির কাজটি পুনরাবৃত্তির চেয়ে অনেক দ্রুত চলে। কারণটি হ'ল পরেরগুলিতে, প্রতিটি আইটেমের CALLজন্য, ফাংশনটির st_pushজন্য একটি প্রয়োজন এবং তারপরে আরেকটি প্রয়োজন st_pop

পূর্ববর্তী সময়ে, আপনার CALLকাছে প্রতিটি নোডের জন্য কেবল পুনরাবৃত্তি রয়েছে ।

এছাড়াও, কলস্ট্যাকের ভেরিয়েবল অ্যাক্সেস করা অবিশ্বাস্যভাবে দ্রুত। এর অর্থ আপনি মেমরি থেকে পড়ছেন যা সর্বদা অন্তঃস্থ ক্যাশে থাকবে। অন্যদিকে, একটি স্পষ্ট স্ট্যাকের সমর্থন করতে হবে malloc: গাদা থেকে এড মেমরি যা অ্যাক্সেস করতে খুব ধীর হয়।

সতর্কতার সাথে অপ্টিমাইজেশন যেমন ইনলাইনিং st_pushএবং st_pop, আমি পুনরাবৃত্তির পদ্ধতির সাথে মোটামুটি সমতাতে পৌঁছতে পারি। তবে কমপক্ষে আমার কম্পিউটারে, হিপ মেমরি অ্যাক্সেস করার জন্য ব্যয় পুনরাবৃত্তিকারী কলের ব্যয়ের চেয়ে বেশি।

তবে এই আলোচনাটি বেশিরভাগ ক্ষেত্রেই অবিচ্ছিন্ন কারণ পুনরাবৃত্ত গাছের হাঁটা ভুল । আপনার যদি পর্যাপ্ত পরিমাণে গাছ থাকে তবে আপনার কলস্ট্যাকের জায়গা শেষ হয়ে যাবে যার কারণে একটি পুনরাবৃত্ত অ্যালগরিদম ব্যবহার করা আবশ্যক।


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

1
7 নোড বাইনারি গাছের 10 ^ 8 বার প্রি-অর্ডার ট্রভারসাল করেছে। পুনরাবৃত্তি 25ns। সুস্পষ্ট স্ট্যাক (বাউন্ড-চেক করা বা না - কোনও পার্থক্যের তেমন কিছু করে না) ns 15ns। পুনরাবৃত্তির জন্য কেবল ধাক্কা এবং জাম্পিং ছাড়াও আরও বেশি কিছু (রেকর্ডিং সঞ্চয় এবং পুনরুদ্ধার + (সাধারণত) কঠোর ফ্রেমের প্রান্তিককরণ) করা দরকার। (এবং এটি গতিশীলভাবে সংযুক্ত লিবিজে পিএলটি-র সাথে আরও খারাপ হয়)) আপনাকে স্পষ্টত স্ট্যাকটি হিপ-বরাদ্দ করার দরকার নেই। আপনি একটি বাধা দিতে পারেন যার প্রথম ফ্রেমটি নিয়মিত কল স্ট্যাকটিতে থাকে যাতে আপনি সবচেয়ে সাধারণ ক্ষেত্রে ক্যাশে লোকালটিকে ত্যাগ না করেন যেখানে আপনি প্রথম ব্লকটি অতিক্রম করেন না।
পিএসকোকিক

3

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

আপনি কারণ সম্পর্কে মাথায় পেরেক আঘাত; স্ট্যাক ফ্রেম তৈরি করা এবং ধ্বংস করা সাধারণ লাফের চেয়ে ব্যয়বহুল।

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

সম্পাদনা: এই উত্তরটি অ-কার্যকরী ভাষাগুলি ধরে নিয়েছে, যেখানে বেশিরভাগ বুনিয়াদি ডেটা ধরণের পরিবর্তনীয়। এটি কার্যকরী ভাষাতে প্রযোজ্য নয়।


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

হাঁ। লেজ পুনরাবৃত্তি কখনও কখনও উভয় বিশ্বের সেরা হতে পারে - একটি পুনরাবৃত্ত টাস্ক বাস্তবায়নের কার্যকরী "উপযুক্ত" উপায় এবং একটি লুপ ব্যবহার করার কর্মক্ষমতা।
আম্বর

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

2

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


1

কার্যকরী প্রোগ্রামিং আরো "হয় কি " বদলে " কিভাবে "।

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

প্রোগ্রামার দৃষ্টিকোণ থেকে যা বেশি গুরুত্বপূর্ণ তা হ'ল পঠনযোগ্যতা এবং রক্ষণাবেক্ষণযোগ্যতা প্রথম স্থানে অপ্টিমাইজেশনের চেয়ে। আবার, "অকালীন অপটিমাইজেশন হ'ল সমস্ত মন্দের মূল"।


0

এটি একটি অনুমান। সাধারণত পুনরাবৃত্তি খুব সহজেই বা কখনও শালীন আকারের সমস্যার ক্ষেত্রে লুপিংকে মারবে না যদি উভয়ই সত্যই ভাল অ্যালগরিদম ব্যবহার করে থাকে (বাস্তবায়নের অসুবিধা গণনা করে না) তবে ডাব্লু / লেজ কল পুনরাবৃত্তি (এবং একটি লেজ পুনরাবৃত্তির অ্যালগরিদম ) ব্যবহার করলে এটি আলাদা হতে পারে এবং ভাষার অংশ হিসাবে লুপগুলি সহ) - যা সম্ভবত খুব মিল থাকে এবং সম্ভবত কিছু সময় পুনরাবৃত্তি পছন্দ করে।


0

তত্ত্ব অনুসারে এটি একই জিনিস। একই ও () জটিলতার সাথে পুনরাবৃত্তি এবং লুপ একই তাত্ত্বিক গতিতে কাজ করবে তবে অবশ্যই বাস্তব গতি ভাষা, সংকলক এবং প্রসেসরের উপর নির্ভর করে। সংখ্যার পাওয়ার সহ উদাহরণটি ও (এলএন (এন)) এর সাথে পুনরাবৃত্তির পথে কোড করা যায়:

  int power(int t, int k) {
  int res = 1;
  while (k) {
    if (k & 1) res *= t;
    t *= t;
    k >>= 1;
  }
  return res;
  }

1
বিগ হে "সমানুপাতিক"। উভয়ই তাই O(n), তবে একজনের জন্য অন্যের চেয়ে অনেক সময় বেশি সময় লাগতে পারেxn
ctrl-alt-delor
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.