मैंने एक सहकर्मी का दावा किया कि 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वेक्टर को म्यूट नहीं करता है।