কোনটি আরও দক্ষ, প্রতিটি জন্য লুপ, বা একটি পুনরুক্তিকারী?


206

কোন সংগ্রহটি পাস করার সবচেয়ে কার্যকর উপায় কোনটি?

List<Integer>  a = new ArrayList<Integer>();
for (Integer integer : a) {
  integer.toString();
}

অথবা

List<Integer>  a = new ArrayList<Integer>();
for (Iterator iterator = a.iterator(); iterator.hasNext();) {
   Integer integer = (Integer) iterator.next();
   integer.toString();
}

দয়া করে মনে রাখবেন, যে এই একজন সঠিক সদৃশ নয় এই , এই , এই , বা এই , যদিও গত প্রশ্নের উত্তর এক বন্ধ আসে। এটি কোনও ডুপ নয়, এর কারণ হ'ল বেশিরভাগগুলি লুপের সাথে তুলনা করে যেখানে আপনি লুপটির get(i)অভ্যন্তরে কল করেন, বার্তাটি ব্যবহার না করে।

প্রস্তাবিত হিসাবে মেটা আমি এই প্রশ্নের আমার উত্তর পোস্ট করা হবে।


আমি মনে করব এটির জাভা এবং টেম্পলেট করার প্রক্রিয়া সিনট্যাকটিক চিনির চেয়ে কিছুটা বেশি নয়
হাসান সৈয়দ


2
@ ওএমজি পনিস: আমি বিশ্বাস করি না যে এটি একটি সদৃশ, কারণ এটি পুনরুক্তির সাথে লুপটির তুলনা করে না, বরং কেন সংগ্রহগুলি পুনরাবৃত্তকারীদের সরাসরি ক্লাসে রাখার পরিবর্তে পুনরাবৃত্তিগুলি ফেরত দেয় তা জিজ্ঞাসা করে।
পল ওয়াগল্যান্ড

উত্তর:


264

আপনি যদি সমস্ত মানটি পড়ার জন্য কেবল সংগ্রহে ঘোরাফেরা করছেন, তবে পুনরুক্তি বা লুপ সিনট্যাক্সের জন্য নতুন ব্যবহারের মধ্যে কোনও পার্থক্য নেই, কারণ নতুন সিনট্যাক্সটি কেবল আয়তাকারটিকে ডুবো জলরূপে ব্যবহার করে।

তবে, আপনি লুপ দ্বারা পুরানো "সি-স্টাইল" লুপটি বোঝাতে চাইছেন:

for(int i=0; i<list.size(); i++) {
   Object o = list.get(i);
}

তারপরে অন্তর্নিহিত ডেটা কাঠামোর উপর নির্ভর করে লুপের জন্য নতুন বা পুনরুক্তিকরণকারী অনেক বেশি দক্ষ হতে পারে। এর কারণ হ'ল কিছু ডেটা স্ট্রাকচারের জন্য get(i)এটি একটি ও (এন) অপারেশন, যা লুপটিকে একটি ও (এন 2 ) অপারেশন করে। একটি traditionalতিহ্যগত লিঙ্কযুক্ত তালিকাই এই জাতীয় ডেটা কাঠামোর উদাহরণ। সমস্ত পুনরাবৃত্তির একটি মৌলিক প্রয়োজনীয়তা রয়েছে যা next()একটি ও (1) অপারেশন হওয়া উচিত, লুপটিকে O (n) তৈরি করে।

লুপ সিনট্যাক্সের জন্য নতুন দ্বারা আউটরেটারটি পানির নীচে ব্যবহার করা হয়েছে তা যাচাই করতে, নিম্নলিখিত দুটি জাভা স্নিপেট থেকে উত্পন্ন বাইকোডগুলি তুলনা করুন। লুপের জন্য প্রথম:

List<Integer>  a = new ArrayList<Integer>();
for (Integer integer : a)
{
  integer.toString();
}
// Byte code
 ALOAD 1
 INVOKEINTERFACE java/util/List.iterator()Ljava/util/Iterator;
 ASTORE 3
 GOTO L2
L3
 ALOAD 3
 INVOKEINTERFACE java/util/Iterator.next()Ljava/lang/Object;
 CHECKCAST java/lang/Integer
 ASTORE 2 
 ALOAD 2
 INVOKEVIRTUAL java/lang/Integer.toString()Ljava/lang/String;
 POP
L2
 ALOAD 3
 INVOKEINTERFACE java/util/Iterator.hasNext()Z
 IFNE L3

এবং দ্বিতীয়, পুনরুক্তি:

List<Integer>  a = new ArrayList<Integer>();
for (Iterator iterator = a.iterator(); iterator.hasNext();)
{
  Integer integer = (Integer) iterator.next();
  integer.toString();
}
// Bytecode:
 ALOAD 1
 INVOKEINTERFACE java/util/List.iterator()Ljava/util/Iterator;
 ASTORE 2
 GOTO L7
L8
 ALOAD 2
 INVOKEINTERFACE java/util/Iterator.next()Ljava/lang/Object;
 CHECKCAST java/lang/Integer
 ASTORE 3
 ALOAD 3
 INVOKEVIRTUAL java/lang/Integer.toString()Ljava/lang/String;
 POP
L7
 ALOAD 2
 INVOKEINTERFACE java/util/Iterator.hasNext()Z
 IFNE L8

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


4
আমি বিশ্বাস করি তিনি বিপরীতে বলছিলেন, foo.get (i) অনেক কম দক্ষ হতে পারে। লিঙ্কলিস্টের কথা ভাবুন। যদি আপনি একটি লিঙ্কলিস্টের মাঝামাঝি একটি foo.get (i) করেন তবে এটিতে পৌঁছাতে পূর্ববর্তী সমস্ত নোডকে অতিক্রম করতে হবে। অন্যদিকে একটি পুনরাবৃত্তকারী অন্তর্নিহিত ডেটা স্ট্রাকচারের একটি হ্যান্ডেল রাখবে এবং আপনাকে নোডের উপরে একবারে হাঁটার অনুমতি দেবে।
মাইকেল ক্রাকলিস

1
কোনও বড় জিনিস নয় তবে for(int i; i < list.size(); i++) {স্টাইলের লুপটি list.size()প্রতিটি পুনরাবৃত্তির শেষেও মূল্যায়ন করতে হবে , যদি এটি ব্যবহার করা হয় তবে list.size()প্রথমটির ফলাফলটি ক্যাশে করার জন্য এটি কখনও কখনও আরও দক্ষ ।
ব্রেট রায়ান

3
আসলে, মূল বিবৃতিটি অ্যারেলিস্ট এবং র্যান্ডমএ্যাক্সেস ইন্টারফেস প্রয়োগকারী অন্য সকলের ক্ষেত্রেও সত্য। "সি-স্টাইল" লুপটি ইটেলার-ভিত্তিকের চেয়ে দ্রুত is docs.oracle.com/javase/7/docs/api/java/util/RandomAccess.html
এবং

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

3
অ্যারেলিস্টের জন্য ঠিক অন্য কোনও মন্তব্য হিসাবে, (int i = 0 ....) লুপটি পুনরাবৃত্তকারী বা (:) পদ্ধতির জন্য ব্যবহারের চেয়ে প্রায় 2x দ্রুত, তাই এটি অন্তর্নিহিত কাঠামোর উপর নির্ভর করে। এবং পার্শ্ব নোট হিসাবে, হ্যাশসেটগুলি পুনরাবৃত্তি করা খুব ব্যয়বহুল (অ্যারে তালিকার চেয়ে অনেক বেশি), সুতরাং প্লেগের মতো তাদের এড়িয়ে চলুন (যদি আপনি পারেন তবে)।
লিও

106

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

যেমন

এটা ঠিক আছে:

Set<Object> set = new HashSet<Object>();
// add some items to the set

Iterator<Object> setIterator = set.iterator();
while(setIterator.hasNext()){
     Object o = setIterator.next();
     if(o meets some condition){
          setIterator.remove();
     }
}

এটি নয়, কারণ এটি একযোগে পরিবর্তন ব্যতিক্রম ছুঁড়ে ফেলবে:

Set<Object> set = new HashSet<Object>();
// add some items to the set

for(Object o : set){
     if(o meets some condition){
          set.remove(o);
     }
}

12
এটি অত্যন্ত সত্য, যদিও এটি তথ্যবহুল হওয়ার জন্য আমি +1 দিয়েছি এমন প্রশ্নের উত্তর দেয় না, এবং যৌক্তিক ফলো-অন প্রশ্নের উত্তর দেয়।
পল ওয়াগল্যান্ড

1
হ্যাঁ আমরা ফোরচ লুপের সাহায্যে সংগ্রহের উপাদানগুলি অ্যাক্সেস করতে পারি তবে আমরা সেগুলি সরাতে পারি না, তবে আমরা আইট্রেটারের সাহায্যে উপাদানগুলি সরাতে পারি।
আকাশ5288

22

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

বর্ধিত forবিবৃতি forফর্মের একটি মৌলিক বক্তব্যের সমতুল্য :

for (I #i = Expression.iterator(); #i.hasNext(); ) {
    VariableModifiers(opt) Type Identifier = #i.next();    
    Statement 
}

অন্য কথায়, জেএলএস দ্বারা এটি প্রয়োজনীয় যে দুটি সমতুল্য। তত্ত্বের অর্থ বাইটোকোডের মধ্যে প্রান্তিক পার্থক্য বোঝাতে পারে তবে বাস্তবে লুপের জন্য বর্ধিত বর্ধনের প্রয়োজন:

  • .iterator()পদ্ধতিটি চাওয়া
  • ব্যবহার .hasNext()
  • এর মাধ্যমে স্থানীয় পরিবর্তনশীল উপলব্ধ করুন available .next()

সুতরাং, অন্য কথায়, সমস্ত ব্যবহারিক উদ্দেশ্যে বাইকোডটি অভিন্ন বা প্রায় অভিন্ন হবে। যে কোনও সংকলক বাস্তবায়নের কল্পনা করা শক্ত, যার ফলশ্রুতি উভয়ের মধ্যে কোনও উল্লেখযোগ্য পার্থক্য রয়েছে।


প্রকৃতপক্ষে, আমি যে পরীক্ষাটি করেছি তা ছিল গ্রহগ্রন্থ সংকলক সহ, তবে আপনার সাধারণ পয়েন্টটি এখনও দাঁড়িয়ে আছে। +1
পল ওয়াগল্যান্ড 22'10

3

foreachUnderhood তৈরি করছেiterator , hasNext () কলিং এবং পরবর্তী কলিং () মান পেতে; পারফরম্যান্সের সাথে সমস্যাটি কেবল তখনই আসে যখন আপনি এমন কিছু ব্যবহার করছেন যা র‌্যান্ডোমঅ্যাক্সেস প্রয়োগ করে।

for (Iterator<CustomObj> iter = customList.iterator(); iter.hasNext()){
   CustomObj custObj = iter.next();
   ....
}

পুনরুক্তি-ভিত্তিক লুপের সাথে পারফরম্যান্স সমস্যাগুলি হ'ল এটি হ'ল:

  1. তালিকাটি ফাঁকা থাকলেও কোনও বস্তু বরাদ্দ করা ( Iterator<CustomObj> iter = customList.iterator(););
  2. iter.hasNext() লুপটির প্রতিটি পুনরাবৃত্তির সময় একটি ইনভোকইন্টারফেস ভার্চুয়াল কল থাকে (সমস্ত শ্রেণীর মধ্য দিয়ে যান, তারপরে জাম্পের আগে মেথড টেবিল লকআপ করুন)।
  3. পুনরাবৃত্তির প্রয়োগের জন্য hasNext()কল চিত্রটি মানটি তৈরি করতে কমপক্ষে 2 টি ক্ষেত্রের সন্ধান করতে হবে : # 1 বর্তমান গণনা পান এবং # 2 মোট গণনা পান
  4. বডি লুপের অভ্যন্তরে, আরেকটি ইনভয়েটারইন্টারফেস ভার্চুয়াল কল রয়েছে iter.next(সুতরাং: সমস্ত ক্লাসের মধ্য দিয়ে যান এবং লাফ দেওয়ার আগে টেবিলের সন্ধান করুন) এবং পাশাপাশি ক্ষেত্রগুলি অনুসন্ধান করতে হবে: # 1 সূচকটি পান এবং # 2 রেফারেন্স পান এটিতে অফসেট করতে অ্যারে (প্রতিটি পুনরাবৃত্তিতে)।

একটি সম্ভাব্য অপটিমাইজেশন হ'লindex iteration ক্যাশেড আকার অনুসন্ধানের সাথে স্যুইচ করা :

for(int x = 0, size = customList.size(); x < size; x++){
  CustomObj custObj = customList.get(x);
  ...
}

আমাদের এখানে আছে:

  1. একটি ইনভয়েন্টারফেস ভার্চুয়াল পদ্ধতি কল customList.size() আকার পেতে লুপ জন্য প্রাথমিক তৈরি করতে
  2. customList.get(x)লুপের জন্য শরীরের সময় পদ্ধতিটি কল করুন যা অ্যারেতে ক্ষেত্রের অনুসন্ধান এবং তারপরে অ্যারেতে অফসেট করতে পারে

আমরা এক টন পদ্ধতি কল, ক্ষেত্রের অনুসন্ধানগুলি হ্রাস করেছি। এটি আপনি LinkedListএমন RandomAccessকোনও কিছুর সাথে বা সংগ্রহ করতে চান না যা সংগ্রহের বিষয় নয় , অন্যথায় এটি customList.get(x)এমন কিছুতে পরিণত হবে যা LinkedListপ্রতিটি পুনরাবৃত্তির উপর দিয়ে যেতে হয়।

এটি নিখুঁত যখন আপনি জানেন যে কোনও RandomAccessভিত্তিক তালিকা সংগ্রহ।


1

foreachহুডের অধীনে পুনরুক্তিগুলি যাইহোক ব্যবহার করে। এটি সত্যিই কেবল সিনট্যাকটিক চিনি।

নিম্নলিখিত প্রোগ্রাম বিবেচনা করুন:

import java.util.List;
import java.util.ArrayList;

public class Whatever {
    private final List<Integer> list = new ArrayList<>();
    public void main() {
        for(Integer i : list) {
        }
    }
}

আসুন এটি দিয়ে সংকলন করুন javac Whatever.java,
এবং main()ব্যবহার করে বিচ্ছিন্ন বাইকোডটি পড়ুন javap -c Whatever:

public void main();
  Code:
     0: aload_0
     1: getfield      #4                  // Field list:Ljava/util/List;
     4: invokeinterface #5,  1            // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
     9: astore_1
    10: aload_1
    11: invokeinterface #6,  1            // InterfaceMethod java/util/Iterator.hasNext:()Z
    16: ifeq          32
    19: aload_1
    20: invokeinterface #7,  1            // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
    25: checkcast     #8                  // class java/lang/Integer
    28: astore_2
    29: goto          10
    32: return

আমরা দেখতে পাচ্ছি যে foreachএটি একটি প্রোগ্রামকে সংকলন করে যা:

  • ব্যবহার করে পুনরুক্তি তৈরি করে List.iterator()
  • যদি Iterator.hasNext(): আহবান করে Iterator.next()এবং লুপ চালিয়ে যায়

হিসাবে "কেন এই বেহুদা লুপটি সংকলিত কোড থেকে অপ্টিমাইজ হয় না? আমরা দেখতে পাচ্ছি যে এটি তালিকা আইটেমটি দিয়ে কিছুই করে না": ভাল, আপনার পুনরাবৃত্তির কোডিং করা আপনার পক্ষে সম্ভব যা .iterator()পার্শ্ব-প্রতিক্রিয়াযুক্ত , বা তাই .hasNext()এর পার্শ্ব প্রতিক্রিয়া বা অর্থপূর্ণ পরিণতি রয়েছে।

আপনি সহজেই কল্পনা করতে পারেন যে কোনও ডাটাবেস থেকে একটি স্ক্রোলযোগ্য ক্যোরির প্রতিনিধিত্বকারী একটি নাটকীয় কিছু নাটকীয় করতে পারে .hasNext() (যেমন ডাটাবেসের সাথে যোগাযোগ করা বা কার্সার বন্ধ করে দেওয়া কারণ আপনি ফলাফলের শেষে পৌঁছে গেছেন)।

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

আমরা সর্বোত্তম আশা করতে পারি এটি একটি সংকলক সতর্কতা । এটা যে আকর্ষণীয় javac -Xlint:all Whatever.javaকরে না আমাদের এই খালি লুপ শরীর সম্পর্কে সতর্ক করুন। ইন্টেলিজ আইডিইএ যদিও করে। স্বীকারোক্তিযুক্ত আমি Ellipse কম্পাইলার ব্যবহার করতে IntelliJ কনফিগার করেছি, তবে এটি কারণ না হতে পারে।

এখানে চিত্র বর্ণনা লিখুন


0

আইট্রেটারটি জাভা সংগ্রহের কাঠামোর একটি ইন্টারফেস যা কোনও সংগ্রহের উপর দিয়ে যেতে বা পুনরুক্ত করার পদ্ধতি সরবরাহ করে।

পুনরাবৃত্তকারী এবং লুপ উভয়ই একইরকম কাজ করে যখন আপনার উদ্দেশ্যটি কেবলমাত্র কোনও উপাদান এর উপাদানগুলি পড়ার জন্য অতিক্রম করে।

for-each সংগ্রহের মাধ্যমে পুনরাবৃত্তি করার একমাত্র উপায়।

উদাহরণ স্বরূপ:

List<String> messages= new ArrayList<>();

//using for-each loop
for(String msg: messages){
    System.out.println(msg);
}

//using iterator 
Iterator<String> it = messages.iterator();
while(it.hasNext()){
    String msg = it.next();
    System.out.println(msg);
}

এবং প্রতিটি লুপ কেবল পুনরাবৃত্তি ইন্টারফেস প্রয়োগকারী বস্তুগুলিতে ব্যবহার করা যেতে পারে।

এখন ফিরে লুপ এবং পুনরুক্তিকরণ ক্ষেত্রে।

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

(দ্রষ্টব্য: পুনরুক্তিকারীর এই কার্যকারিতাটি কেবল জাভা.ইটিল প্যাকেজে সংগ্রহ শ্রেণীর ক্ষেত্রে প্রযোজ্য conc এটি সহজাত সংগ্রহগুলির জন্য প্রযোজ্য নয় কারণ তারা প্রকৃতির দ্বারা ব্যর্থ-নিরাপদ)


1
পার্থক্য সম্পর্কে আপনার বক্তব্যটি সত্য নয়, প্রতিটি লুপের জন্যও পানির নীচে একটি পুনরুক্তি ব্যবহার করে এবং তাই একই আচরণ করে has
পল ওয়াগল্যান্ড

Wagland @Pault, আমি ভুল ইশারা জন্য আমার উত্তর সংশোধন করেছেন তোমাকে ধন্যবাদ
eccentricCoder

আপনার আপডেটগুলি এখনও সঠিক নয়। আপনার দ্বারা দুটি কোড স্নিপেটগুলি ভাষাটি একই হিসাবে সংজ্ঞায়িত করা হয়েছে। আচরণে যদি কোনও পার্থক্য থাকে যা বাস্তবায়নে একটি বাগ g পার্থক্য হ'ল আপনার পুনরাবৃত্তির অ্যাক্সেস আছে কি না।
পল ওয়াগল্যান্ড

@ পল ওয়াগল্যান্ড এমনকি যদি আপনি পুনরুক্তি ব্যবহার করে এমন প্রতিটি লুপের ডিফল্ট বাস্তবায়ন ব্যবহার করেন তবে আপনি যদি সাম্প্রতিক ক্রিয়াকলাপগুলির সময় অপসারণ () পদ্ধতিটি ব্যবহার করার চেষ্টা করেন তবে তা ফেলে দেওয়া এবং ব্যতিক্রম হবে। আরও তথ্যের জন্য নিম্নলিখিত চেকআউট এখানে
eccentricCoder

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

-8

সংগ্রহগুলির সাথে কাজ করার সময় আমাদের লুপের জন্য traditionalতিহ্যগত ব্যবহার এড়ানো উচিত। আমি যে সহজ কারণটি দিচ্ছি তা হ'ল লুপের জটিলতা হ'ল অর্ডার O (sqr (n)) এবং Iterator এর জটিলতা বা লুপের জন্য বর্ধিত পরিমাণটি কেবল ও (এন)। সুতরাং এটি পারফরমেন্স পার্থক্য দেয় .. মাত্র 1000 টি আইটেমের একটি তালিকা নিন এবং উভয় উপায়ে এটি মুদ্রণ করুন। এবং কার্যকর করার জন্য সময়ের পার্থক্যও মুদ্রণ করুন। আপনি পার্থক্য দেখতে পারেন।


আপনার বিবৃতি সমর্থন করতে দয়া করে কিছু উদাহরণস্বরূপ উদাহরণ যুক্ত করুন।
রাজেশ পিট্টি

@ চন্দন দুঃখিত, আপনি যা লিখেছেন তা ভুল। উদাহরণস্বরূপ: std :: ভেক্টরও একটি সংগ্রহ তবে এর অ্যাক্সেসের জন্য ও (1) ব্যয় হয়। সুতরাং কোনও ভেক্টরের উপর লুপের জন্য একটি traditionalতিহ্যবাহী কেবল ও (এন)। আমি মনে করি আপনি বলতে চান, যদি আন্ডারলাইং কনটেইনার অ্যাক্সেসের ও (অ) এর অ্যাক্সেস ব্যয় থাকে, তবে এটি স্ট্যান্ড :: তালিকার জন্য, ও (ity n ^ 2) এর জটিলতার চেয়ে বেশি। সেক্ষেত্রে পুনরাবৃত্তকারীগুলি ব্যবহারের ফলে ও (N) এর ব্যয় হ্রাস পাবে, কারণ পুনরাবৃত্তকারীরা উপাদানগুলিতে সরাসরি অ্যাক্সেসের অনুমতি দেয়।
কায়সার

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