আমি একজন সহকর্মীকে দাবী করেছি যে 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
সংকলকটিতে এটি প্রমাণ করতে সমস্যা হতে পারে যা ভেক্টরকে রূপান্তরিত করে না।