tôi bị tấn cùng một thử nghiệm các chức năng khác nhau ở đây, và đây là những gì tôi đã đưa ra:
write_ushort: 7,81 s
uShortToStr: 8,16 s
convert : 6.71 s
use_sprintf: 49.66 s
(Write_ushort là phiên bản của tôi, mà tôi đã cố gắng viết rõ ràng là p có thể, thay vì vi tối ưu hóa, để định dạng thành một bộ đệm ký tự đã cho; use_sprintf là sprintf rõ ràng (buf, "% d", x) và không có gì khác; hai câu còn lại được lấy từ các câu trả lời khác ở đây.)
Đây là một sự khác biệt khá tuyệt vời giữa chúng, phải không? Ai có thể nghĩ rằng để sử dụng sprintf phải đối mặt với gần như một thứ tự của sự khác biệt độ lớn? Ồ, vâng, tôi đã lặp lại từng chức năng thử nghiệm bao nhiêu lần?
// Taken directly from my hacked up test, but should be clear.
// Compiled with gcc 4.4.3 and -O2. This test is interesting, but not authoritative.
int main() {
using namespace std;
char buf[100];
#define G2(NAME,STMT) \
{ \
clock_t begin = clock(); \
for (int count = 0; count < 3000; ++count) { \
for (unsigned x = 0; x <= USHRT_MAX; ++x) { \
NAME(x, buf, sizeof buf); \
} \
} \
clock_t end = clock(); \
STMT \
}
#define G(NAME) G2(NAME,) G2(NAME,cout << #NAME ": " << double(end - begin)/CLOCKS_PER_SEC << " s\n";)
G(write_ushort)
G(uShortToStr)
G(convert)
G(use_sprintf)
#undef G
#undef G2
return 0;
}
sprintf chuyển đổi các toàn bộ phạm vi có thể của quần short unsigned, sau đó đã làm toàn bộ phạm vi lại hơn 2.999 lần vào khoảng 0,25 ms cho mỗi chuyển đổi, trung bình, trên máy tính xách tay ~ 5 tuổi của tôi.
Sprintf là di động; nó cũng đủ hiệu quả cho các yêu cầu của bạn?
phiên bản của tôi:
// Returns number of non-null bytes written, or would be written.
// If ret is null, does not write anything; otherwise retlen is the length of
// ret, and must include space for the number plus a terminating null.
int write_ushort(unsigned short x, char *ret, int retlen) {
assert(!ret || retlen >= 1);
char s[uint_width_10<USHRT_MAX>::value]; // easy implementation agnosticism
char *n = s;
if (x == 0) {
*n++ = '0';
}
else while (x != 0) {
*n++ = '0' + x % 10;
x /= 10;
}
int const digits = n - s;
if (ret) {
// not needed by checking retlen and only writing to available space
//assert(retlen >= digits + 1);
while (--retlen && n != s) {
*ret++ = *--n;
}
*ret = '\0';
}
return digits;
}
Compile-time log chức năng TMP là không có gì mới, nhưng trong đó có ví dụ hoàn chỉnh này bởi vì đó là những gì tôi đã sử dụng:
template<unsigned N>
struct uint_width_10_nonzero {
enum { value = uint_width_10_nonzero<N/10>::value + 1 };
};
template<>
struct uint_width_10_nonzero<0> {
enum { value = 0 };
};
template<unsigned N>
struct uint_width_10 {
enum { value = uint_width_10_nonzero<N>::value };
};
template<>
struct uint_width_10<0> {
enum { value = 1 };
};
Các bạn đã thử sử dụng ' sprintf'/'snprintf'? Đã làm như vậy, có bạn đã lược tả mã và xác định rằng đây là điểm phát sóng hiệu suất không? –
Các bảng ở dưới cùng của bài viết được liên kết dưới đây minh họa rõ ràng nơi triển khai stdlib cư trú ở mức độ hiệu quả và tối ưu của việc triển khai có liên quan: http://www.codeproject.com/KB/recipes/Tokenizer.aspx –