यहाँ कुछ कोड है (पूरा कार्यक्रम सवाल में बाद में इस प्रकार):अनुकूलन
template <typename T>
T fizzbuzz(T n) {
T count(0);
#if CONST
const T div(3);
#else
T div(3);
#endif
for (T i(0); i <= n; ++i) {
if (i % div == T(0)) count += i;
}
return count;
}
अब, अगर मैं int
के साथ इस टेम्पलेट फ़ंक्शन को कॉल करें, तो मैं के अनुसार 6 प्रदर्शन अंतर का एक पहलू मिल क्या मैं cONST या नहीं परिभाषित:
$ gcc --version
gcc (GCC) 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)
$ make -B wrappedint CPPFLAGS="-O3 -Wall -Werror -DWRAP=0 -DCONST=0" &&
time ./wrappedint
g++ -O3 -Wall -Werror -DWRAP=0 -DCONST=0 wrappedint.cpp -o wrappedi
nt
484573652
real 0m2.543s
user 0m2.059s
sys 0m0.046s
$ make -B wrappedint CPPFLAGS="-O3 -Wall -Werror -DWRAP=0 -DCONST=1" &&
time ./wrappedint
g++ -O3 -Wall -Werror -DWRAP=0 -DCONST=1 wrappedint.cpp -o wrappedi
nt
484573652
real 0m0.655s
user 0m0.327s
sys 0m0.046s
disassembly की जांच से पता चलता तेज (स्थिरांक) मामले में, सापेक्ष धीमी गति से (गैर स्थिरांक) मामले में एक गुणा और पाली प्रकार बात में बदल दिया गया, जबकि यहका उपयोग कर रहा है 0।
भी बदतर है, अगर मैं एक कक्षा में मेरी पूर्णांक रैप करने के लिए प्रयास करते हैं, तो अनुकूलन है कि क्या मैं स्थिरांक या नहीं का उपयोग नहीं होता है। कोड हमेशा idivl
का उपयोग करता है और धीमी गति से चलाता है:
#include <iostream>
struct WrappedInt {
int v;
explicit WrappedInt(const int &val) : v(val) {}
bool operator<=(const WrappedInt &rhs) const { return v <= rhs.v; }
bool operator==(const WrappedInt &rhs) const { return v == rhs.v; }
WrappedInt &operator++() { ++v; return *this; }
WrappedInt &operator+=(const WrappedInt &rhs) { v += rhs.v; return *this; }
WrappedInt operator%(const WrappedInt &rhs) const
{ return WrappedInt(v%rhs.v); }
};
std::ostream &operator<<(std::ostream &s, WrappedInt w) {
return s << w.v;
}
template <typename T>
T fizzbuzz(T n) {
T count(0);
#if CONST
const T div(3);
#else
T div(3);
#endif
for (T i(0); i <= n; ++i) {
if (i % div == T(0)) count += i;
}
return count;
}
int main() {
#if WRAP
WrappedInt w(123456789);
std::cout << fizzbuzz(w) << "\n";
#else
std::cout << fizzbuzz<int>(123456789) << "\n";
#endif
}
मेरे प्रश्न हैं:
1) वहाँ सी ++ ही, या जीसीसी के अनुकूलन है, जो बताते हैं कि ऐसा क्यों होता की एक सरल सिद्धांत है, या यह सिर्फ एक है "विभिन्न हेरिस्टिक्स रन के मामले में, यह वह कोड है जिसे आप प्राप्त करते हैं"?
2) क्या कंपाइलर को यह एहसास करने का कोई तरीका है कि मेरे स्थानीय रूप से घोषित और कभी-संदर्भित कॉन्स्ट रैपप्डआईंट को संकलन-समय का मूल्य मान माना जा सकता है? मैं चाहता हूं कि यह चीज़ टेम्पलेट्स में int के लिए एक सीधी प्रतिस्थापन हो।
3) वहाँ एक पूर्णांक ऐसा है कि संकलक जब अनुकूलन के रैपिंग त्यागने कर सकते हैं लपेटकर का एक ज्ञात तरीका है? लक्ष्य यह है कि WrappedInt नीति-आधारित टेम्पलेट होगा। लेकिन अगर इंट पर अनिवार्य रूप से मनमाना 6x गति दंड में "डू-कुछ नहीं" नीति परिणाम होता है, तो मैं उस परिस्थिति को विशेष रूप से बंद कर रहा हूं और सीधे int का उपयोग कर रहा हूं।
मामले में यह किसी भी भ्रम का कारण बनता - मैं शायद अपने समारोह "सीटी" नाम दिया जाना चाहिए था जब मैं "|| मैं% 5" ;-) –