मैंने एक सहकर्मी का दावा किया कि if (i < input.size() - 1) print(0);
इस पाश में अनुकूलित किया जाएगा ताकि input.size()
हर पुनरावृत्ति में न पढ़ा जाए , लेकिन यह पता चला है कि यह मामला नहीं है!
void print(int x) {
std::cout << x << std::endl;
}
void print_list(const std::vector<int>& input) {
int i = 0;
for (size_t i = 0; i < input.size(); i++) {
print(input[i]);
if (i < input.size() - 1) print(0);
}
}
संकलक एक्सप्लोरर के अनुसार gcc विकल्पों के साथ -O3 -fno-exceptions
हम वास्तव में input.size()
प्रत्येक पुनरावृत्ति को पढ़ रहे हैं और lea
घटाव का उपयोग कर रहे हैं!
movq 0(%rbp), %rdx
movq 8(%rbp), %rax
subq %rdx, %rax
sarq $2, %rax
leaq -1(%rax), %rcx
cmpq %rbx, %rcx
ja .L35
addq $1, %rbx
दिलचस्प है, जंग में यह अनुकूलन होता है। ऐसा लगता है कि i
एक चर के साथ प्रतिस्थापित किया जाता है j
जिसे प्रत्येक पुनरावृत्ति को घटाया जाता है, और परीक्षण i < input.size() - 1
को कुछ के साथ बदल दिया जाता है j > 0
।
fn print(x: i32) {
println!("{}", x);
}
pub fn print_list(xs: &Vec<i32>) {
for (i, x) in xs.iter().enumerate() {
print(*x);
if i < xs.len() - 1 {
print(0);
}
}
}
में संकलक एक्सप्लोरर प्रासंगिक विधानसभा इस तरह दिखता है:
cmpq %r12, %rbx
jae .LBB0_4
मैं जाँच की और मैं कर रहा हूँ यकीन है कि r12
है xs.len() - 1
और rbx
काउंटर है। इससे पहले एक के add
लिए rbx
और mov
पाश के बाहर में है r12
।
ऐसा क्यों है? ऐसा लगता है जैसे कि जीसीसी इनलाइन को सक्षम करने में सक्षम है size()
और operator[]
जैसा कि उसने किया, यह जानना चाहिए कि size()
यह परिवर्तन नहीं करता है। लेकिन हो सकता है कि जीसीसी के ऑप्टिमाइज़र ने जज किया हो कि इसे एक चर में खींचने के लायक नहीं है? या हो सकता है कि कुछ अन्य संभावित दुष्प्रभाव हैं जो इस असुरक्षित बना देंगे - क्या कोई जानता है?
cout.operator<<()
। कंपाइलर को पता नहीं है कि इस ब्लैक-बॉक्स फ़ंक्शन को std::vector
वैश्विक से संदर्भ नहीं मिलता है ।
println
या operator<<
कुंजी है।
println
शायद एक जटिल तरीका है, संकलक को यह साबित करने में परेशानी हो सकती है किprintln
वेक्टर को म्यूट नहीं करता है।