मैं जावा में नया हूं, और कल रात कुछ कोड चला रहा था, और इसने मुझे परेशान कर दिया। मैं लूप के लिए हर एक्स आउटपुट को प्रदर्शित करने के लिए एक सरल प्रोग्राम बना रहा था, और मैंने प्रदर्शन में कमी देखी, जब मैंने variable % variable
बनाम variable % 5000
या व्हाट्सएप के रूप में मापांक का उपयोग किया । क्या कोई मुझे समझा सकता है कि यह क्यों है और यह क्या कारण है? तो मैं बेहतर हो सकता है ...
यहाँ "कुशल" कोड है (क्षमा करें अगर मुझे थोड़ा सा वाक्यविन्यास गलत मिला तो मैं अभी कोड वाले कंप्यूटर पर नहीं हूँ)
long startNum = 0;
long stopNum = 1000000000L;
for (long i = startNum; i <= stopNum; i++){
if (i % 50000 == 0) {
System.out.println(i);
}
}
यहाँ "अक्षम कोड" है
long startNum = 0;
long stopNum = 1000000000L;
long progressCheck = 50000;
for (long i = startNum; i <= stopNum; i++){
if (i % progressCheck == 0) {
System.out.println(i);
}
}
ध्यान रखें कि मेरे पास मतभेदों को मापने के लिए एक दिनांक चर था, और एक बार जब यह काफी लंबा हो गया, तो पहले वाले ने 50ms लिए जबकि दूसरे ने 12 सेकंड या ऐसा ही कुछ लिया। यदि आपका पीसी खदान से अधिक कुशल है या नहीं तो आपको बढ़ाना stopNum
या घटाना पड़ सकता है progressCheck
।
मैंने वेब पर इस प्रश्न की तलाश की, लेकिन मुझे इसका उत्तर नहीं मिला, शायद मैं इसे सही नहीं कह रहा हूँ।
संपादित करें: मुझे उम्मीद नहीं थी कि मेरा प्रश्न इतना लोकप्रिय होगा, मैं सभी उत्तरों की सराहना करता हूं। मैंने प्रत्येक आधे समय में एक बेंचमार्क का प्रदर्शन किया, और अक्षम कोड काफी लंबा समय लगा, 1/4 एक सेकंड बनाम 10 सेकंड दे या ले। दी है कि वे प्रिंटलाइन का उपयोग कर रहे हैं, लेकिन वे दोनों एक ही राशि कर रहे हैं, इसलिए मैं कल्पना नहीं करूंगा कि यह बहुत तिरछा होगा, खासकर जब से विसंगति दोहराने योग्य है। जवाब के लिए, चूंकि मैं जावा में नया हूं, इसलिए मैं वोटों को अभी तय करने दूंगा कि कौन सा जवाब सबसे अच्छा है। मैं बुधवार तक इसे चुनने की कोशिश करूंगा।
EDIT2: मैं आज रात एक और परीक्षण करने जा रहा हूं, जहां मापांक के बजाय, यह केवल एक चर बढ़ाता है, और जब यह प्रगति पर पहुंचता है, तो यह एक प्रदर्शन करेगा, और फिर उस चर को 0. एक 3 विकल्प के लिए रीसेट कर देगा।
EDIT3.5:
मैंने इस कोड का उपयोग किया है, और नीचे मैं अपने परिणाम दिखाऊंगा .. अद्भुत मदद के लिए धन्यवाद! मैंने भी लंबे समय से 0 के छोटे मूल्य की तुलना करने की कोशिश की, इसलिए मेरे सभी नए चेक कभी-कभी "65536" बार दोहराते हैं।
public class Main {
public static void main(String[] args) {
long startNum = 0;
long stopNum = 1000000000L;
long progressCheck = 65536;
final long finalProgressCheck = 50000;
long date;
// using a fixed value
date = System.currentTimeMillis();
for (long i = startNum; i <= stopNum; i++) {
if (i % 65536 == 0) {
System.out.println(i);
}
}
long final1 = System.currentTimeMillis() - date;
date = System.currentTimeMillis();
//using a variable
for (long i = startNum; i <= stopNum; i++) {
if (i % progressCheck == 0) {
System.out.println(i);
}
}
long final2 = System.currentTimeMillis() - date;
date = System.currentTimeMillis();
// using a final declared variable
for (long i = startNum; i <= stopNum; i++) {
if (i % finalProgressCheck == 0) {
System.out.println(i);
}
}
long final3 = System.currentTimeMillis() - date;
date = System.currentTimeMillis();
// using increments to determine progressCheck
int increment = 0;
for (long i = startNum; i <= stopNum; i++) {
if (increment == 65536) {
System.out.println(i);
increment = 0;
}
increment++;
}
//using a short conversion
long final4 = System.currentTimeMillis() - date;
date = System.currentTimeMillis();
for (long i = startNum; i <= stopNum; i++) {
if ((short)i == 0) {
System.out.println(i);
}
}
long final5 = System.currentTimeMillis() - date;
System.out.println(
"\nfixed = " + final1 + " ms " + "\nvariable = " + final2 + " ms " + "\nfinal variable = " + final3 + " ms " + "\nincrement = " + final4 + " ms" + "\nShort Conversion = " + final5 + " ms");
}
}
परिणाम:
- निश्चित = 874 एमएस (सामान्य रूप से लगभग 1000 सेमी, लेकिन 2 की शक्ति होने के कारण तेजी से)
- चर = 8590 एमएस
- अंतिम चर = 1944 एमएस (50000 का उपयोग करते समय (~ 1000 मी।)
- वेतन वृद्धि = 1904 एमएस
- लघु रूपांतरण = 679 एमएस
आश्चर्य की बात नहीं है, विभाजन की कमी के कारण, लघु रूपांतरण "तेज" तरीके से 23% तेज था। यह नोट करना दिलचस्प है। यदि आपको प्रत्येक 256 बार (या वहां के बारे में) कुछ दिखाने या तुलना करने की आवश्यकता है, तो आप ऐसा कर सकते हैं, और उपयोग कर सकते हैं
if ((byte)integer == 0) {'Perform progress check code here'}
एक अंतिम अंतर नोट, 65536 के साथ "अंतिम घोषित चर" पर मापांक का उपयोग करते हुए (एक सुंदर संख्या नहीं) निश्चित मूल्य की तुलना में धीमी (धीमी) थी। जहां पहले यह उसी गति के निकट बेंचमार्किंग कर रहा था।
final
सामने जोड़ता हूंprogressCheck
, तो दोनों फिर से उसी गति से चलते हैं। यह मुझे विश्वास दिलाता है कि संकलक या JIT लूप को अनुकूलित करने का प्रबंधन करता है जब यह जानता है किprogressCheck
यह स्थिर है।