if (i < input.size() - 1) print(0);Bu döngüde optimize edilecek bir iş arkadaşına iddia ettim, böylece input.size()her yinelemede okunmaz, ancak durum böyle değil!
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 seçeneklerine sahip Derleyici Gezgini'ne göre -O3 -fno-exceptionsaslında input.size()her bir yinelemeyi okuyor ve leaçıkarma yapmak için kullanıyoruz !
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
İlginçtir, Rust'ta bu optimizasyon gerçekleşir. Her yinelemede azaltılmış ibir değişkenle değiştirilmiş gibi görünüyor jve test i < input.size() - 1gibi bir şeyle değiştiriliyor 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);
}
}
}
In Derleyici Explorer ilgili montaj şuna benzer:
cmpq %r12, %rbx
jae .LBB0_4
Kontrol ettim ve ben eminim r12olduğunu xs.len() - 1ve rbxsayaç olduğunu. Daha önce bir addfor rbxve bir movdış döngü vardır r12.
Bu neden? Görünüşe göre GCC satır içi yapabiliyorsa size()ve operator[]olduğu gibi, bunun size()değişmediğini de bilmeli . Ama belki GCC'nin optimize edici, onu bir değişkene çekmeye değmeyeceğine karar verir? Ya da belki de bunu güvensiz hale getirecek başka bir olası yan etkisi vardır - kimse biliyor mu?
cout.operator<<(). Derleyici, bu kara kutu işlevinin std::vectorbir genel öğeden bir başvuru almadığını bilmiyor .
printlnya operator<<da anahtar olduğu konusunda haklısınız .
printlnmuhtemelen karmaşık bir yöntemdir, derleyiciprintlnvektörü değiştirmediğini kanıtlamakta sorun yaşayabilir .