একটি লুপ এবং প্রতিটি লুপের জন্য একটি পারফরম্যান্স পার্থক্য আছে?


184

নিম্নলিখিত দুটি লুপের মধ্যে পারফরম্যান্সের পার্থক্য কী?

for (Object o: objectArrayList) {
    o.DoSomething();
}

এবং

for (int i=0; i<objectArrayList.size(); i++) {
    objectArrayList.get(i).DoSomething();
}

@ কেপারো: এটি "প্রতিটি" লুপ একটি "ইন-ইন" লুপ নয়
অ্যান্ডি টার্নার

জাভাতে একে "প্রত্যেকের জন্য" বলা হয়, তবে যখন এটি উদ্দেশ্য সি তে আসে তখন এটি "ইন" লুপ বলে।
দামিথ


লুপ পারফরম্যান্সের জন্য বাড়ানো এখানে আলোচনা হয়: stackoverflow.com/questions/12155987/...
eckes

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

উত্তর:


212

জোশুয়া ব্লচের কার্যকর জাভাতে আইটেম 46 থেকে :

রিলিজ ১.০ এ প্রবর্তিত প্রতিটি লুপটি বিশৃঙ্খলা থেকে মুক্তি এবং পুনরুক্তি বা সূচক ভেরিয়েবল সম্পূর্ণরূপে গোপন করে ত্রুটির সুযোগ পেয়ে যায়। ফলস্বরূপ আইডিয়োম সংগ্রহ এবং অ্যারেগুলিতে সমানভাবে প্রযোজ্য:

// The preferred idiom for iterating over collections and arrays
for (Element e : elements) {
    doSomething(e);
}

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


48
প্রতিটি লুপের জন্য কোনও সূচকের কাউন্টারে অ্যাক্সেস করার কোনও উপায় নেই (যেহেতু এটি বিদ্যমান নেই)
বাসসারো

হ্যাঁ, তবে সেই কাউন্টারটি এখন লুপের বাইরে দৃশ্যমান। অবশ্যই, এটি একটি সাধারণ ফিক্স তবে এটি প্রত্যেকের জন্য!
ইন্দোলারিং

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

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

3
@ gsingh2011 অ্যান্ড্রয়েড ডক্স ( ডেভেলপার.অ্যান্ড্রয়েড / ট্রাইনিং / আর্টিকেলস / স্পাফ -টিপস HTTML# লুপস ) উল্লেখ করেছে যে কেবলমাত্র অ্যারেলিস্টের উপর পূর্বাভাস ব্যবহার করার সময় আপনার একটি পারফরম্যান্স জরিমানা হবে, অন্য সংগ্রহগুলি নয়। আমি কি কৌতুহল যে আপনার ক্ষেত্রে ছিল কিনা।
ভিস্কারি

29

এই সমস্ত লুপগুলি ঠিক একই কাজ করে, আমি আমার দুটি সেন্টে ফেলে দেওয়ার আগে এগুলি প্রদর্শন করতে চাই।

প্রথমত, তালিকার মাধ্যমে লুপিংয়ের সর্বোত্তম উপায়:

for (int i=0; i < strings.size(); i++) { /* do something using strings.get(i) */ }

দ্বিতীয়ত, পছন্দসই উপায়টি যেহেতু এটির ত্রুটি কম রয়েছে (আপনি কতবার "উফগুলি করেছেন, লুপগুলির মধ্যে এই লুপগুলিতে i এবং j ভেরিয়েবলগুলি মিশিয়েছেন?)"।

for (String s : strings) { /* do something using s */ }

তৃতীয়ত, লুপের জন্য মাইক্রো-অনুকূলিতকরণ:

int size = strings.size();
for (int i = -1; ++i < size;) { /* do something using strings.get(i) */ }

এখন আসল দুটি সেন্ট: আমি যখন এগুলি পরীক্ষা করছিলাম, তৃতীয়টি তখন মিলি সেকেন্ডগুলি গণনা করার সময় দ্রুততম ছিল যখন এটি একটি সাধারণ ক্রিয়াকলাপের সাথে প্রতিটি ধরণের লুপের জন্য কয়েক মিলিয়ন বার বার বার বলেছিল - এটি জাভা 5 ব্যবহার করছিল উইন্ডোতে jre1.6u10 এর সাথে যদি কারও আগ্রহ থাকে।

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

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


5
দয়া করে নোট করুন যে ++ i <= আকারযুক্ত লুপটি "1-ভিত্তিক", উদাহরণস্বরূপ লুপের অভ্যন্তরীণ পদ্ধতিটি 1, 2, 3, ইত্যাদির জন্য ডাকা হবে
ভলিতে

15
মাইক্রো-অপ্টিমাইজড লুপটি লেখার একটি আরও ভাল উপায় হ'ল (int i = 0, আকার = স্ট্রিংস.সাইজ (); ++ i <= আকার;) {} এটি পছন্দনীয় কারণ এটি আকারের পরিধি কমিয়ে দেয়
ডেনাল

1
তৃতীয়টি প্রথম বার i = 1 থেকে শুরু হয় না যখন এটি প্রথম উপাদানটি এড়িয়ে যায় লুপের মধ্য দিয়ে যায়। এবং এটি লুপের জন্য হওয়া অপ্রয়োজনীয়। int n = স্ট্রিং.সৌধ; (n -> 0) {System.out.println ("" + n + "" + স্ট্রিং [এন]); }
লাসি কিনুনুনে

1
@ ডোনাল যে লুপ প্যাটার্নটি প্রথমটি মিস করে এবং একটি আইওওবি দেয়। এটি একটির জন্য কাজ করে: (int i = -1, আকার = list.size (); ++ i <আকার;)
নাথান অ্যাডামস

1
"এই সমস্ত লুপগুলি ঠিক একই কাজ করে" ভুল। একটি এলোমেলো অ্যাক্সেস ব্যবহার করে get(int), অন্যটি ব্যবহার করে Iterator। এটি একটি এন বার করায় যেহেতু LinkedListএর পারফরম্যান্সটি for(int i=0;i<strings.size();i++) { /* do something using strings.get(i) */ }আরও খারাপ কোথায় তা বিবেচনা করুন get(int)
স্টিভ কুও

13

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

আমার মনে হয় নিবন্ধটি এখানে রয়েছে: নতুন অবস্থান

এখানে প্রদর্শিত লিঙ্কটি মারা গিয়েছিল।


12

ঠিক আছে, পারফরম্যান্সের প্রভাবটি বেশিরভাগ ক্ষেত্রে তুচ্ছ, তবে শূন্য নয়। আপনি যদি RandomAccessইন্টারফেসের জাভাক ডকটি দেখুন :

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

for (int i=0, n=list.size(); i < n; i++)
    list.get(i);

এই লুপের চেয়ে দ্রুত চলে:

for (Iterator i=list.iterator(); i.hasNext();)
      i.next();

এবং প্রতিটি লুপটি পুনরাবৃত্তকারী সহ সংস্করণ ব্যবহার করছে, ArrayListউদাহরণস্বরূপ, প্রতিটি লুপটি দ্রুততম হয় না।


সত্যিই প্রতিটি? এমনকি একটি অ্যারে সঙ্গে? আমি এখানে স্ট্যাকওভারফ্লো.com/ প্রশ্নগুলি / 1006395/ … পড়েছি যে এটিতে কোনও পুনরুক্তিকারী জড়িত না।
ওন্দ্র Žižka

@ ওন্দ্রাŽাইকা: প্রতিটি লুপ এসের উপর লুপ করার সময় পুনরুক্তি ব্যবহার করে Iterableতবে অ্যারে নয়। অ্যারেগুলির জন্য একটি সূচক ভেরিয়েবল সহ একটি লুপ ব্যবহার করা হয়। জেএলএস এ সম্পর্কে তথ্য আছে ।
লিই

হ্যাঁ, আপনার প্রথমে এটি ব্যয় করে টু অ্যারে দিয়ে একটি অ্যারে তৈরি করা দরকার।
লাসি কিনুনুনে

6

দুর্ভাগ্যক্রমে একটি পার্থক্য রয়েছে বলে মনে হচ্ছে।

আপনি যদি উভয় ধরণের লুপের জন্য জেনারেটেড বাইটস কোডটি দেখেন তবে সেগুলি ভিন্ন।

এখানে Log4j উত্স কোড থেকে একটি উদাহরণ দেওয়া আছে।

/ লগ ৪ জ- এপি / এসআরসি / মেইন / জাভা / অর্গ /পাছে / ব্লগিং / লোগোজেজে / মার্কারম্যানেজার.জভাতে আমাদের লোগোজেজার্কার নামে একটি স্ট্যাটিক অভ্যন্তরীণ শ্রেণি রয়েছে যা সংজ্ঞায়িত করে:

    /*
     * Called from add while synchronized.
     */
    private static boolean contains(final Marker parent, final Marker... localParents) {
        //noinspection ForLoopReplaceableByForEach
        for (final Marker marker : localParents) {
            if (marker == parent) {
                return true;
            }
        }
        return false;
    }

স্ট্যান্ডার্ড লুপ সহ:

  private static boolean contains(org.apache.logging.log4j.Marker, org.apache.logging.log4j.Marker...);
    Code:
       0: iconst_0
       1: istore_2
       2: aload_1
       3: arraylength
       4: istore_3
       5: iload_2
       6: iload_3
       7: if_icmpge     29
      10: aload_1
      11: iload_2
      12: aaload
      13: astore        4
      15: aload         4
      17: aload_0
      18: if_acmpne     23
      21: iconst_1
      22: ireturn
      23: iinc          2, 1
      26: goto          5
      29: iconst_0
      30: ireturn

প্রত্যেকের জন্য:

  private static boolean contains(org.apache.logging.log4j.Marker, org.apache.logging.log4j.Marker...);
    Code:
       0: aload_1
       1: astore_2
       2: aload_2
       3: arraylength
       4: istore_3
       5: iconst_0
       6: istore        4
       8: iload         4
      10: iload_3
      11: if_icmpge     34
      14: aload_2
      15: iload         4
      17: aaload
      18: astore        5
      20: aload         5
      22: aload_0
      23: if_acmpne     28
      26: iconst_1
      27: ireturn
      28: iinc          4, 1
      31: goto          8
      34: iconst_0
      35: ireturn

ওরাকল দিয়ে কী হবে?

আমি জাভা 7 এবং 8 এর সাথে উইন্ডোজ 7 এ চেষ্টা করেছি।


7
যারা বিচ্ছিন্নতা পড়তে চাইছেন তাদের নেট ফলাফলটি লুপের অভ্যন্তরে উত্পন্ন কোডটি অভিন্ন, তবে প্রতিটি সেটআপ দ্বিতীয় যুক্তির রেফারেন্স যুক্ত একটি অতিরিক্ত অস্থায়ী পরিবর্তনশীল তৈরি করেছে বলে মনে হয়। যদি অতিরিক্ত লুকানো ভেরিয়েবলটি নিবন্ধভুক্ত করা হয় তবে প্যারামিটারটি কোড উত্পন্নকরণের সময় না হয়, তবে প্রতিটিটির জন্য প্রতিটি দ্রুত হবে; যদি (;;) উদাহরণে প্যারামিটারটি নিবন্ধভুক্ত থাকে তবে কার্যকর করার সময়টি অভিন্ন হবে। গ্যাট্টা বেঞ্চমার্ক?
রবিন ডেভিস

4

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


10
আমি মনে করি পারফরম্যান্স অপটিমাইজেশনে "সর্বদা" বলে কোনও জিনিস নেই))

4

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

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

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


4

নিম্নলিখিত কোড:

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;

interface Function<T> {
    long perform(T parameter, long x);
}

class MyArray<T> {

    T[] array;
    long x;

    public MyArray(int size, Class<T> type, long x) {
        array = (T[]) Array.newInstance(type, size);
        this.x = x;
    }

    public void forEach(Function<T> function) {
        for (T element : array) {
            x = function.perform(element, x);
        }
    }
}

class Compute {
    int factor;
    final long constant;

    public Compute(int factor, long constant) {
        this.factor = factor;
        this.constant = constant;
    }

    public long compute(long parameter, long x) {
        return x * factor + parameter + constant;
    }
}

public class Main {

    public static void main(String[] args) {
        List<Long> numbers = new ArrayList<Long>(50000000);
        for (int i = 0; i < 50000000; i++) {
            numbers.add(i * i + 5L);
        }

        long x = 234553523525L;

        long time = System.currentTimeMillis();
        for (int i = 0; i < numbers.size(); i++) {
            x += x * 7 + numbers.get(i) + 3;
        }
        System.out.println(System.currentTimeMillis() - time);
        System.out.println(x);
        x = 0;
        time = System.currentTimeMillis();
        for (long i : numbers) {
            x += x * 7 + i + 3;
        }
        System.out.println(System.currentTimeMillis() - time);
        System.out.println(x);
        x = 0;
        numbers = null;
        MyArray<Long> myArray = new MyArray<Long>(50000000, Long.class, 234553523525L);
        for (int i = 0; i < 50000000; i++) {
            myArray.array[i] = i * i + 3L;
        }
        time = System.currentTimeMillis();
        myArray.forEach(new Function<Long>() {

            public long perform(Long parameter, long x) {
                return x * 8 + parameter + 5L;
            }
        });
        System.out.println(System.currentTimeMillis() - time);
        System.out.println(myArray.x);
        myArray = null;
        myArray = new MyArray<Long>(50000000, Long.class, 234553523525L);
        for (int i = 0; i < 50000000; i++) {
            myArray.array[i] = i * i + 3L;
        }
        time = System.currentTimeMillis();
        myArray.forEach(new Function<Long>() {

            public long perform(Long parameter, long x) {
                return new Compute(8, 5).compute(parameter, x);
            }
        });
        System.out.println(System.currentTimeMillis() - time);
        System.out.println(myArray.x);
    }
}

আমার সিস্টেমে নিম্নলিখিত ফলাফল দেয়:

224
-699150247503735895
221
-699150247503735895
220
-699150247503735895
219
-699150247503735895

আমি ওরাকলজেডকে 1.7 আপডেট 6 দিয়ে উবুন্টু 12.10 আলফা চালাচ্ছি।

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

অন্যদিকে, লিংকডলিস্টে ইন্ডেক্সড গেট লিংকডলিস্টের জন্য পুনরাবৃত্তির কাছে কল করার চেয়ে ধীর গতির যাতে আপনি পুনরাবৃত্তি ব্যবহার করার সময় পাঠযোগ্যতা ধরে রাখার সময় সেই কার্যকারিতাটি হিট করতে পারবেন (প্রতিটি লুপের ক্ষেত্রে স্পষ্ট বা স্পষ্টতই)।


3

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


প্রথম লুপটিতে প্রতিটি উপাদানও পেতে হয়। এটি করার জন্য এটি দৃশ্যের পিছনে একটি পুনরুক্তি তৈরি করে। তারা সত্যিই সমতুল্য।
বিল

সি হিসাবে বিবেচনা করে, একটি পুনরুক্তিকারী কেবল একটি পয়েন্টার বৃদ্ধি করতে পারে, তবে একটি প্রাপ্তি প্রতিবার পয়েন্টারের প্রস্থের দ্বারা i এর মানকে গুণতে হয়।
পল টমবলিন

এটি নির্ভর করে আপনি কোন ধরণের তালিকা ব্যবহার করেন। আমি মনে করি আপনি ঠিক আছেন যদিও, গেট ব্যবহার করা কখনই দ্রুত এবং কখনও কখনও ধীর হয় না।
বিল করুন


3

এখানে অ্যানড্রয়েড বিকাশকারী দলের পার্থক্য সম্পর্কে একটি সংক্ষিপ্ত বিশ্লেষণ দেওয়া হল:

https://www.youtube.com/watch?v=MZOf3pOAM6A

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


2

চলক নাম দ্বারা objectArrayList, আমি ধরে নিই যে এটির একটি উদাহরণ java.util.ArrayList। সেক্ষেত্রে পারফরম্যান্সের পার্থক্যটি অবিস্মরণীয় হবে।

অন্যদিকে, এটির উদাহরণস্বরূপ java.util.LinkedList, List#get(int)ও (এন) ক্রিয়াকলাপ হওয়ায় দ্বিতীয় পদ্ধতিটি অনেক ধীর হবে ।

সুতরাং লুপটিতে যুক্তি দ্বারা সূচক প্রয়োজন না হলে প্রথম পদ্ধতির সর্বদা পছন্দ করা হয় is


1
1. for(Object o: objectArrayList){
    o.DoSomthing();
}
and

2. for(int i=0; i<objectArrayList.size(); i++){
    objectArrayList.get(i).DoSomthing();
}

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


1

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


1

গৃহীত উত্তর প্রশ্নের উত্তর দেয়, অ্যারেলিস্টের ব্যতিক্রমী মামলা বাদে ...

যেহেতু বেশিরভাগ বিকাশকারী অ্যারেলিস্টের উপর নির্ভর করে (অন্তত আমি এটি বিশ্বাস করি)

সুতরাং আমি এখানে সঠিক উত্তর যুক্ত করতে বাধ্য।

সরাসরি বিকাশকারী ডকুমেন্টেশন থেকে: -

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

একটি অ্যারের মাধ্যমে পুনরাবৃত্তি করার জন্য বেশ কয়েকটি বিকল্প রয়েছে:

static class Foo {
    int mSplat;
}

Foo[] mArray = ...

public void zero() {
    int sum = 0;
    for (int i = 0; i < mArray.length; ++i) {
        sum += mArray[i].mSplat;
    }
}

public void one() {
    int sum = 0;
    Foo[] localArray = mArray;
    int len = localArray.length;

    for (int i = 0; i < len; ++i) {
        sum += localArray[i].mSplat;
    }
}

public void two() {
    int sum = 0;
    for (Foo a : mArray) {
        sum += a.mSplat;
    }
}

শূন্য () সবচেয়ে ধীরতম, কারণ লুপের মাধ্যমে প্রতিটি পুনরাবৃত্তির জন্য একবার অ্যারে দৈর্ঘ্য পাওয়ার ব্যয়টিকে জেআইটি এখনও অনুকূল করতে পারে না।

এক () দ্রুত। এটি চেহারাগুলিকে এড়িয়ে সমস্ত কিছু স্থানীয় ভেরিয়েবলের মধ্যে টান দেয়। কেবল অ্যারের দৈর্ঘ্য একটি কার্যকারিতা সুবিধা দেয়।

দুটি () একটি জেআইটিবিহীন ডিভাইসের জন্য দ্রুত এবং একটি জেআইটি সহ ডিভাইসগুলির জন্য এক () থেকে পৃথক। এটি জাভা প্রোগ্রামিং ভাষার 1.5 সংস্করণে প্রবর্তিত লুপ সিনট্যাক্স ব্যবহার করে।

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


-2

হ্যাঁ, for-eachবৈকল্পিক স্বাভাবিকের চেয়ে দ্রুতindex-based-for-loop

for-eachবৈকল্পিক ব্যবহার iterator। সুতরাং ট্র্যাভারসিং স্বাভাবিক forলুপের চেয়ে দ্রুত যা সূচক ভিত্তিক।
এটি কারণ iteratorট্র্যাভার্সিংয়ের জন্য অনুকূলিত হয়েছে, কারণ এটি পরের উপাদানটির ঠিক আগে এবং পূর্ববর্তী উপাদানটির ঠিক পরে ইশারা করছে । পড়ার কারণ এক index-based-for-loopধীর হতে যে, এটা করতে হবে নিরূপণ এবং উপাদান অবস্থানে প্রতিটি সময় সরাতে যা দিয়ে নয় iterator


-3
public class FirstJavaProgram {

    public static void main(String[] args) 
    {
        int a[]={1,2,3,45,6,6};

// Method 1: this is simple way to print array 

        for(int i=0;i<a.length;i++) 
        { 
            System.out.print(a[i]+" ");
        }

// Method 2: Enhanced For loop

        for(int i:a)
        {
            System.out.print(i+" ");
        }
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.