আমি জাভাতে এমন কিছু কোড লিখছি যেখানে কোনও পর্যায়ে প্রোগ্রামটির প্রবাহটি "ইন" এবং "বি" দুটি ইনট ভেরিয়েবলগুলি শূন্য নয় কিনা তা দ্বারা নির্ধারিত হয় (দ্রষ্টব্য: a এবং b কখনই নেতিবাচক নয় এবং কখনও পূর্ণসংখ্যার ওভারফ্লো সীমার মধ্যে নেই)।
আমি এটি দিয়ে মূল্যায়ন করতে পারি
if (a != 0 && b != 0) { /* Some code */ }
বা বিকল্পভাবে
if (a*b != 0) { /* Some code */ }
যেহেতু আমি প্রত্যাশা করি যে কোডটির টুকরোটি প্রতি রানে কয়েক মিলিয়ন বার চালিত হবে, আমি ভাবছিলাম যে কোনটি দ্রুত হবে। আমি এগুলি এলোমেলোভাবে উত্পন্ন অ্যারেগুলির সাথে তুলনা করে পরীক্ষাটি করেছিলাম এবং অ্যারে এর স্পারসিটি (ডেটা ভগ্নাংশ = 0) ফলাফলকে কীভাবে প্রভাবিত করবে তা দেখার জন্যও আমি আগ্রহী ছিলাম:
long time;
final int len = 50000000;
int arbitrary = 0;
int[][] nums = new int[2][len];
for (double fraction = 0 ; fraction <= 0.9 ; fraction += 0.0078125) {
for(int i = 0 ; i < 2 ; i++) {
for(int j = 0 ; j < len ; j++) {
double random = Math.random();
if(random < fraction) nums[i][j] = 0;
else nums[i][j] = (int) (random*15 + 1);
}
}
time = System.currentTimeMillis();
for(int i = 0 ; i < len ; i++) {
if( /*insert nums[0][i]*nums[1][i]!=0 or nums[0][i]!=0 && nums[1][i]!=0*/ ) arbitrary++;
}
System.out.println(System.currentTimeMillis() - time);
}
এবং ফলাফলগুলি দেখায় যে আপনি যদি "ক" বা "বি" সময়ের ~ 3% এর চেয়ে 0 এর সমান হতে আশা করেন তবে তার চেয়ে a*b != 0
দ্রুততর a!=0 && b!=0
:
আমি কেন জানতে আগ্রহী। কেউ কি কিছু আলোকপাত করতে পারে? এটি কি সংকলক বা এটি হার্ডওয়্যার স্তরে?
সম্পাদনা: কৌতূহলের বাইরে ... এখন যখন আমি শাখার পূর্বাভাস সম্পর্কে জানতে পেরেছিলাম, তখন আমি ভাবছিলাম যে অ্যানালগ তুলনাটি একটি ওআর বি-এর জন্য কী প্রদর্শিত হবে:
আমরা প্রত্যাশা অনুযায়ী শাখার পূর্বাভাসের একই প্রভাব দেখতে পাই, মজার বিষয় হল গ্রাফটি কিছুটা এক্স-অক্ষের সাথে বিচ্ছিন্ন হয়ে গেছে।
হালনাগাদ
1- আমি !(a==0 || b==0)
বিশ্লেষণে যুক্ত করে দেখি কী ঘটে।
2- আমি এছাড়াও অন্তর্ভুক্ত করা a != 0 || b != 0
, (a+b) != 0
এবং (a|b) != 0
আউট কৌতুহল, শাখা ভবিষ্যদ্বাণী সম্পর্কে জানতে হয়। তবে এগুলি যুক্তিগতভাবে অন্যান্য অভিব্যক্তির সমতুল্য নয়, কারণ সত্যটিতে প্রত্যাবর্তনের জন্য কেবল একটি ওআর বি শূন্য হওয়া দরকার, তাই প্রক্রিয়াজাতকরণের দক্ষতার জন্য সেগুলি তুলনা করে বোঝানো হয় না।
3- আমি বিশ্লেষণের জন্য যে সত্যিকারের মানদণ্ডটি ব্যবহার করেছি তা যুক্ত করেছিলাম, যা কেবল একটি স্বেচ্ছাসেবীর ইনট ভেরিয়েবলটি পুনরাবৃত্তি করে।
4- কিছু লোক এর a != 0 & b != 0
বিপরীতে অন্তর্ভুক্ত করার পরামর্শ দিচ্ছিল a != 0 && b != 0
, ভবিষ্যদ্বাণী সহ যে এটি আরও ঘনিষ্ঠভাবে আচরণ করবে a*b != 0
কারণ আমরা শাখার পূর্বাভাসের প্রভাবটি সরিয়ে দেব। আমি জানি না যে এটি &
বুলিয়ান ভেরিয়েবলগুলির সাথে ব্যবহার করা যেতে পারে, আমি ভেবেছিলাম এটি কেবলমাত্র পূর্ণসংখ্যার সাথে বাইনারি অপারেশনের জন্য ব্যবহৃত হয়েছিল।
দ্রষ্টব্য: আমি যে সমস্ত প্রসঙ্গে বিবেচনা করছিলাম, প্রচ্ছন্ন ওভারফ্লো কোনও সমস্যা নয়, তবে সাধারণ প্রসঙ্গে এটি অবশ্যই একটি গুরুত্বপূর্ণ বিবেচনা।
সিপিইউ: ইনটেল কোর i7-3610QM @ 2.3GHz
জাভা সংস্করণ: 1.8.0_45
জাভা (টিএম) এসই রানটাইম এনভায়রনমেন্ট (বিল্ড 1.8.0_45-বি 14)
জাভা হটস্পট (টিএম) 64-বিট সার্ভার ভিএম (বিল্ড 25.45-বি02, মিশ্র মোড)
a != 0 & b != 0
।
a*b!=0
এর একটি কম শাখা আছে
(1<<16) * (1<<16) == 0
তবু উভয়ই শূন্য থেকে পৃথক।
a*b
শূন্য যদি এক এর a
এবং b
শূন্য হয়; a|b
উভয় হলেই শূন্য।
if (!(a == 0 || b == 0))
? মাইক্রোবেঞ্চমার্কগুলি কুখ্যাতভাবে বিশ্বাসযোগ্য নয়, এটি সত্যিই পরিমাপযোগ্য হওয়ার সম্ভাবনা নেই (to 3% আমার কাছে ত্রুটির প্রান্তিকের মতো শোনায়)।