আমি একজন সহকর্মীকে দাবী করেছি যে 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);
}
}
জিসিসি বিকল্পগুলির সাথে সংকলক এক্সপ্লোরার অনুযায়ী -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সংকলকটিতে এটি প্রমাণ করতে সমস্যা হতে পারে যা ভেক্টরকে রূপান্তরিত করে না।