foreach
লুপ , যোগ জাভা 5 (নামেও "লুপ জন্য উন্নত"), একটি ব্যবহার সমতূল্য java.util.Iterator
একই জিনিসের জন্য --it এর অন্বিত চিনি। সুতরাং, প্রতিটি উপাদান পড়ার সময় একে একে এবং foreach
যথাযথভাবে একটি পুনরুক্তিকারীর উপরে সর্বদা একটি চয়ন করা উচিত, কারণ এটি আরও সুবিধাজনক এবং সংক্ষিপ্ত।
প্রতিটির জন্য, প্রত্যেকটির জন্য
for(int i : intList) {
System.out.println("An element in the list: " + i);
}
iterator
Iterator<Integer> intItr = intList.iterator();
while(intItr.hasNext()) {
System.out.println("An element in the list: " + intItr.next());
}
এমন পরিস্থিতি রয়েছে যেখানে আপনাকে অবশ্যই Iterator
সরাসরি ব্যবহার করতে হবে । উদাহরণস্বরূপ, একটি ক্যান ব্যবহার করার সময় কোনও উপাদান মোছার চেষ্টা করা foreach
(উইল?) এর ফলে ক ConcurrentModificationException
।
foreach
বনাম for
: বেসিক পার্থক্য
মধ্যে শুধুমাত্র ব্যবহারিক পার্থক্য for
এবং foreach
যে, সূচিযোগ্য বস্তুর ক্ষেত্রে, আপনি সূচক এক্সেস হবে না। যখন মৌলিক for
লুপটি প্রয়োজন হয় তখন একটি উদাহরণ :
for(int i = 0; i < array.length; i++) {
if(i < 5) {
// Do something special
} else {
// Do other stuff
}
}
যদিও আপনি ম্যানুয়ালি আলাদা আলাদা সূচক ইন্ট-ভেরিয়েবল এর সাথে তৈরি করতে পারেন foreach
,
int idx = -1;
for(int i : intArray) {
idx++;
...
}
এটি সুপারিশ করা হয় না, যেহেতু ভেরিয়েবল-স্কোপটি আদর্শ নয়, এবং বুনিয়াদি for
লুপটি কেবল এই ব্যবহারের ক্ষেত্রে আদর্শ এবং প্রত্যাশিত বিন্যাস।
foreach
বনাম for
: পারফরম্যান্স
যখন সংগ্রহের অ্যাক্সেস, একটি foreach
হল উল্লেখযোগ্যভাবে দ্রুততর মৌলিক চেয়ে for
লুপ এর অ্যারে অ্যাক্সেস। অ্যারে অ্যাক্সেস করার সময়, যদিও - অন্তত আদিম এবং মোড়ক-অ্যারে সহ - সূচীর মাধ্যমে অ্যাক্সেস নাটকীয়ভাবে দ্রুত হয়।
প্রারম্ভিক ইন-অ্যারেগুলির জন্য পুনরাবৃত্তকারী এবং সূচক অ্যাক্সেসের মধ্যে পার্থক্যের সময় নির্ধারণ করা
অ্যাক্সেস বা অ্যারে করার সময় সূচকগুলি পুনরাবৃত্তির তুলনায় 23- 40 শতাংশ দ্রুত হয় । এই পোস্টের নীচে টেস্টিং ক্লাস থেকে আউটপুট এখানে দেওয়া হয়েছে, যা 100-উপাদানগুলির আদিম-আন্ত অ্যারেতে সংখ্যার যোগফল দেয় (A পুনরুত্থক, বি সূচক হয়):int
Integer
[C:\java_code\]java TimeIteratorVsIndexIntArray 1000000
Test A: 358,597,622 nanoseconds
Test B: 269,167,681 nanoseconds
B faster by 89,429,941 nanoseconds (24.438799231635727% faster)
[C:\java_code\]java TimeIteratorVsIndexIntArray 1000000
Test A: 377,461,823 nanoseconds
Test B: 278,694,271 nanoseconds
B faster by 98,767,552 nanoseconds (25.666236154695838% faster)
[C:\java_code\]java TimeIteratorVsIndexIntArray 1000000
Test A: 288,953,495 nanoseconds
Test B: 207,050,523 nanoseconds
B faster by 81,902,972 nanoseconds (27.844689860906513% faster)
[C:\java_code\]java TimeIteratorVsIndexIntArray 1000000
Test A: 375,373,765 nanoseconds
Test B: 283,813,875 nanoseconds
B faster by 91,559,890 nanoseconds (23.891659337194227% faster)
[C:\java_code\]java TimeIteratorVsIndexIntArray 1000000
Test A: 375,790,818 nanoseconds
Test B: 220,770,915 nanoseconds
B faster by 155,019,903 nanoseconds (40.75164734599769% faster)
[C:\java_code\]java TimeIteratorVsIndexIntArray 1000000
Test A: 326,373,762 nanoseconds
Test B: 202,555,566 nanoseconds
B faster by 123,818,196 nanoseconds (37.437545972215744% faster)
আমি এটি Integer
অ্যারের জন্যও চালিয়েছি, এবং সূচকগুলি এখনও স্পষ্ট বিজয়ী, তবে কেবল 18 থেকে 25 শতাংশের মধ্যে দ্রুত।
সংগ্রহের জন্য, পুনরাবৃত্তিগুলি সূচকের চেয়ে দ্রুত
একটি জন্য List
এর Integers
অবশ্য iterators স্পষ্ট বিজয়ী হয়। কেবল পরীক্ষার শ্রেণিতে অন্তর্-অ্যারেটি পরিবর্তন করুন:
List<Integer> intList = Arrays.asList(new Integer[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100});
আর পরীক্ষা ফাংশন প্রয়োজনীয় পরিবর্তন করুন ( int[]
থেকে List<Integer>
, length
থেকে size()
, ইত্যাদি):
[C:\java_code\]java TimeIteratorVsIndexIntegerList 1000000
Test A: 3,429,929,976 nanoseconds
Test B: 5,262,782,488 nanoseconds
A faster by 1,832,852,512 nanoseconds (34.326681820485675% faster)
[C:\java_code\]java TimeIteratorVsIndexIntegerList 1000000
Test A: 2,907,391,427 nanoseconds
Test B: 3,957,718,459 nanoseconds
A faster by 1,050,327,032 nanoseconds (26.038700083921256% faster)
[C:\java_code\]java TimeIteratorVsIndexIntegerList 1000000
Test A: 2,566,004,688 nanoseconds
Test B: 4,221,746,521 nanoseconds
A faster by 1,655,741,833 nanoseconds (38.71935684115413% faster)
[C:\java_code\]java TimeIteratorVsIndexIntegerList 1000000
Test A: 2,770,945,276 nanoseconds
Test B: 3,829,077,158 nanoseconds
A faster by 1,058,131,882 nanoseconds (27.134122749113843% faster)
[C:\java_code\]java TimeIteratorVsIndexIntegerList 1000000
Test A: 3,467,474,055 nanoseconds
Test B: 5,183,149,104 nanoseconds
A faster by 1,715,675,049 nanoseconds (32.60101667104192% faster)
[C:\java_code\]java TimeIteratorVsIndexIntList 1000000
Test A: 3,439,983,933 nanoseconds
Test B: 3,509,530,312 nanoseconds
A faster by 69,546,379 nanoseconds (1.4816434912159906% faster)
[C:\java_code\]java TimeIteratorVsIndexIntList 1000000
Test A: 3,451,101,466 nanoseconds
Test B: 5,057,979,210 nanoseconds
A faster by 1,606,877,744 nanoseconds (31.269164666060377% faster)
একটি পরীক্ষায় তারা প্রায় সমান, তবে সংগ্রহের সাথে পুনরাবৃত্তির জয় হয়।
* এই পোস্টটি স্ট্যাক ওভারফ্লোতে আমি যে দুটি উত্তর লিখেছি তার উপর ভিত্তি করে:
আরও কিছু তথ্য: কোনটি আরও দক্ষ, প্রতিটি লুপের জন্য বা একটি পুনরুক্তিযোগ্য?
সম্পূর্ণ পরীক্ষার ক্লাস
স্ট্যাক ওভারফ্লোতে এই প্রশ্নটি পড়ার পরে আমি এই তুলনা-সময়ের-তুলনায়-কোনও-দুটি-জিনিস শ্রেণীর তৈরি করেছি :
import java.text.NumberFormat;
import java.util.Locale;
/**
<P>{@code java TimeIteratorVsIndexIntArray 1000000}</P>
@see <CODE><A HREF="/programming/180158/how-do-i-time-a-methods-execution-in-java">/programming/180158/how-do-i-time-a-methods-execution-in-java</A></CODE>
**/
public class TimeIteratorVsIndexIntArray {
public static final NumberFormat nf = NumberFormat.getNumberInstance(Locale.US);
public static final void main(String[] tryCount_inParamIdx0) {
int testCount;
// Get try-count from a command-line parameter
try {
testCount = Integer.parseInt(tryCount_inParamIdx0[0]);
}
catch(ArrayIndexOutOfBoundsException | NumberFormatException x) {
throw new IllegalArgumentException("Missing or invalid command line parameter: The number of testCount for each test. " + x);
}
//Test proper...START
int[] intArray = new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100};
long lStart = System.nanoTime();
for(int i = 0; i < testCount; i++) {
testIterator(intArray);
}
long lADuration = outputGetNanoDuration("A", lStart);
lStart = System.nanoTime();
for(int i = 0; i < testCount; i++) {
testFor(intArray);
}
long lBDuration = outputGetNanoDuration("B", lStart);
outputGetABTestNanoDifference(lADuration, lBDuration, "A", "B");
}
private static final void testIterator(int[] int_array) {
int total = 0;
for(int i = 0; i < int_array.length; i++) {
total += int_array[i];
}
}
private static final void testFor(int[] int_array) {
int total = 0;
for(int i : int_array) {
total += i;
}
}
//Test proper...END
//Timer testing utilities...START
public static final long outputGetNanoDuration(String s_testName, long l_nanoStart) {
long lDuration = System.nanoTime() - l_nanoStart;
System.out.println("Test " + s_testName + ": " + nf.format(lDuration) + " nanoseconds");
return lDuration;
}
public static final long outputGetABTestNanoDifference(long l_aDuration, long l_bDuration, String s_aTestName, String s_bTestName) {
long lDiff = -1;
double dPct = -1.0;
String sFaster = null;
if(l_aDuration > l_bDuration) {
lDiff = l_aDuration - l_bDuration;
dPct = 100.00 - (l_bDuration * 100.0 / l_aDuration + 0.5);
sFaster = "B";
}
else {
lDiff = l_bDuration - l_aDuration;
dPct = 100.00 - (l_aDuration * 100.0 / l_bDuration + 0.5);
sFaster = "A";
}
System.out.println(sFaster + " faster by " + nf.format(lDiff) + " nanoseconds (" + dPct + "% faster)");
return lDiff;
}
//Timer testing utilities...END
}