Tôi đã lược tả một đoạn mã nhỏ là một phần của mô phỏng lớn hơn, và ngạc nhiên của tôi, hàm STL bằng (std :: equal) chậm hơn nhiều so với một vòng lặp đơn giản, so sánh hai phần tử mảng theo phần tử . Tôi đã viết một trường hợp thử nghiệm nhỏ, mà tôi tin là một sự so sánh công bằng giữa hai, và sự khác biệt, bằng cách sử dụng g + + 6.1.1 từ lưu trữ Debian không phải là không đáng kể. Tôi đang so sánh hai, bốn phần tử mảng của các số nguyên đã ký. Tôi đã thử nghiệm std :: bằng, toán tử == và một vòng lặp nhỏ. Tôi đã không sử dụng std :: chrono cho một thời gian chính xác, nhưng sự khác biệt có thể được nhìn thấy một cách rõ ràng với thời gian.tại sao là std :: bằng nhiều chậm hơn so với một vòng tay cán cho hai nhỏ :: mảng?
Câu hỏi của tôi là, được cung cấp mã mẫu bên dưới, tại sao toán tử == và hàm bị quá tải std :: bằng (mà gọi toán tử == tôi tin) mất khoảng 40 giây để hoàn tất và vòng viết tay chỉ mất 8 giây ? Tôi đang sử dụng một máy tính xách tay intel rất gần đây. Vòng lặp for nhanh hơn trên tất cả các mức tối ưu hóa, -O1, -O2, -O3 và -Ofast. Tôi biên soạn mã với g++ -std=c++14 -Ofast -march=native -mtune=native
Các vòng lặp chạy một số lượng lớn các lần, chỉ để tạo sự khác biệt rõ ràng bằng mắt thường. Các toán tử modulo đại diện cho một hoạt động giá rẻ trên một trong các phần tử mảng và phục vụ để giữ trình biên dịch không tối ưu hóa vòng lặp.
#include<iostream>
#include<algorithm>
#include<array>
using namespace std;
using T = array<int32_t, 4>;
bool
are_equal_manual(const T& L, const T& R)
noexcept {
bool test{ true };
for(uint32_t i{0}; i < 4; ++i) { test = test && (L[i] == R[i]); }
return test;
}
bool
are_equal_alg(const T& L, const T& R)
noexcept {
bool test{ equal(cbegin(L),cend(L),cbegin(R)) };
return test;
}
int main(int argc, char** argv) {
T left{ {0,1,2,3} };
T right{ {0,1,2,3} };
cout << boolalpha << are_equal_manual(left,right) << endl;
cout << boolalpha << are_equal_alg(left,right) << endl;
cout << boolalpha << (left == right) << endl;
bool t{};
const size_t N{ 5000000000 };
for(size_t i{}; i < N; ++i) {
//t = left == right; // SLOW
//t = are_equal_manual(left,right); // FAST
t = are_equal_alg(left,right); // SLOW
left[0] = i % 10;
right[2] = i % 8;
}
cout<< boolalpha << t << endl;
return(EXIT_SUCCESS);
}
Không thể tạo lại kết quả của bạn. Cả ba phiên bản đều có cùng hiệu suất, mặc dù tôi mong đợi bạn sẽ chậm hơn vì nó luôn chạy vòng lặp đến cuối (trong khi nó có thể dừng ngay khi nó chạm vào một cặp phần tử không so sánh bằng nhau). – Leon
[Đầu ra lắp ráp] (https://godbolt.org/g/L5ioi4), so sánh thủ công là chưa được kiểm soát cmpl, trong khi 'bằng' và' == 'đang sử dụng' memcmp' –
Leon - Tôi đã có thể tái tạo nó trên coliru cũng. Bạn đã thử chạy mã với liên kết tôi đã cung cấp chưa? Bạn đang sử dụng phiên bản GCC nào và trên nền tảng nào? – KBentley57