Cho rằng các thay thế cho phương pháp này là phải có một số lượng lớn các bản xây dựng, đều có một cái gì đó như thế này trong nó:
int main()
{
printf(
#ifdef SWEDISH
"Hej världen\n"
#elsif ENGLISH
"Hello, World\n"
#elsif PORTUGUESE
"Olá, Mundo\n"
#else
#error Language not specified.
#endif
);
return 0l;
}
thay vì chúng tôi nhận được:
int main()
{
printf(gettext("Hello, World\n"));
}
đó là dễ dàng để đọc và hiểu.
Tôi không biết cấu trúc chính xác của triển khai gettext, nhưng tôi cho rằng đó là bảng băm khi nó được tải. Có thể là cây nhị phân, nhưng bảng băm có vẻ hợp lý hơn.
Đối với chi phí chính xác, rất khó để đặt một số trên đó - đặc biệt, như bạn nói, nếu có thứ gì đó được đổi vào đĩa và đĩa đã dừng, phải mất 3-4 giây để lấy đĩa đến tốc độ. Vậy làm thế nào để bạn định lượng? Có, có thể trang cần thiết cho gettext
được hoán đổi nếu hệ thống đang bận làm việc gì đó bộ nhớ chuyên sâu.
Tải tệp tin tin nhắn chỉ nên là phí lớn nếu tệp quá lớn, nhưng một lần nữa, nếu đĩa không quay, và tệp không được lưu trong bộ nhớ cache thì sẽ có một vài giây. Một lần nữa, làm thế nào để định lượng đó. Kích thước của tệp rõ ràng tỷ lệ thuận với kích thước thực tế của các bản dịch (hoặc ngôn ngữ bản địa).
Về điểm 2:
Theo như tôi biết, trong cả Linux và Windows, các trang được đổi chỗ ra vào một "thời gian gần đây nhất là sử dụng" (hoặc một số sử dụng thống kê khác) cơ sở, trong đó có liên quan gì đến nơi họ đang ở. Rõ ràng các thông điệp đã dịch ở một nơi khác với mã thực tế - không có danh sách 15 bản dịch khác nhau trong tệp nguồn, do đó các bản dịch được tải trong thời gian chạy và sẽ được đặt ở một vị trí khác với chính mã.Tuy nhiên, chi phí của việc này là tương tự như sự khác biệt giữa chi phí:
static const char *msg = "Hello, World\n";
và
static const char *msg = strdup("Hello, World\n");
Cho rằng văn bản chuỗi thường được lưu giữ cùng trong nhị phân của một chương trình dù sao, tôi không nghĩ rằng "sự gần gũi" của chúng đối với mã thực thi có sự khác biệt đáng kể so với một mảng bộ nhớ được phân bổ động ở đâu đó trong heap. Nếu bạn gọi hàm gettext
thường đủ, bộ nhớ đó sẽ được giữ "hiện tại" và không được hoán đổi. Nếu bạn không gọi gettext
trong một thời gian, nó có thể bị hoán đổi. Nhưng điều đó áp dụng cho "không có chuỗi nào được lưu trữ trong tệp thi hành đã được sử dụng gần đây, vì vậy chúng đã được hoán đổi".
3) Tôi nghĩ tiếng Anh (hoặc "không chọn ngôn ngữ") được xử lý chính xác giống với bất kỳ biến thể ngôn ngữ nào khác.
tôi sẽ có một chút đào hơn nữa trong một chút, cần ăn sáng đầu tiên ...
Rất không khoa học:
#include <libintl.h>
#include <cstdio>
#include <cstring>
static __inline__ unsigned long long rdtsc(void)
{
unsigned hi, lo;
__asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
return ((unsigned long long)lo)|(((unsigned long long)hi)<<32);
}
int main()
{
char str[10000] = {};
char *s = str;
unsigned long long time;
for(int i = 0; i < 10; i++)
{
time = rdtsc();
s += sprintf(s, "Hello, World %d", i);
time = rdtsc() - time;
printf("Time =%lld\n", time);
}
printf("s = %s\n", str);
s = str;
strcpy(s, "");
for(int i = 0; i < 10; i++)
{
time = rdtsc();
s += sprintf(s, gettext("Hello, World %d"), i);
time = rdtsc() - time;
printf("Time =%lld\n", time);
}
printf("s = %s\n", str);
}
Cung cấp cho kết quả như sau:
$ g++ -Wall -O2 intl.cpp
$ ./a.out
Time =138647
Time =9528
Time =6710
Time =5537
Time =5785
Time =5427
Time =5406
Time =5453
Time =5644
Time =5431
s = Hello, World 0Hello, World 1Hello, World 2Hello, World 3Hello, World 4Hello, World 5Hello, World 6Hello, World 7Hello, World 8Hello, World 9
Time =85965
Time =11929
Time =1
Time =10226
Time =10628
Time =9613
Time =9515
Time =9336
Time =9440
Time =9095
s = Hello, World 0Hello, World 1Hello, World 2Hello, World 3Hello, World 4Hello, World 5Hello, World 6Hello, World 7Hello, World 8Hello, World 9
Các mã trong dcigettext.c
sử dụng hỗn hợp tìm kiếm nhị phân trong một mảng phẳng của chuỗi và hàm băm có chứa chuỗi để băm PJW (xem: http://www.cs.hmc.edu/~geoff/classes/hmc.cs070.200101/homework10/hashfuncs.html).
Vì vậy, chi phí, khi ứng dụng đã bắt đầu, có vẻ như là "chỉ đáng chú ý" (khi đếm đồng hồ), nhưng không lớn.
Thời gian chính xác để chạy sprintf
đầu tiên có phần khác nhau trong cả hai trường hợp, vì vậy tôi sẽ không nói rằng "sử dụng gettext" làm cho sprintf nhanh hơn trong lần gọi đầu tiên - chỉ "may mắn" trong lần chạy này (I đã có một vài biến thể khác của mã và tất cả chúng thay đổi rất nhiều vào lần gọi đầu tiên đến sprintf
và ít hơn cho các cuộc gọi sau này). Có lẽ một số thiết lập (có thể cache [printf gây ra cache được ghi đè với rác khác là khá có thể], dự đoán chi nhánh, vv) một nơi nào đó mà mất thêm thời gian ...
Bây giờ, điều này rõ ràng không trả lời câu hỏi của bạn về phân trang ra ngoài, vv Và tôi đã không cố gắng tạo một bản dịch tiếng Thụy Điển, tiếng Bồ Đào Nha hoặc tiếng Đức của thông điệp "Hello, World" của tôi. Tôi vẫn tin rằng nó không lớn, trừ khi bạn thực sự chạy 100 giây instantiations của một ứng dụng trong một giây, và ứng dụng đó không làm được gì khác ngoài việc in một tin nhắn tới màn hình sau khi thực hiện một số phép tính đơn giản, chắc chắn, nó có thể quan trọng .
Cách duy nhất REAL để tìm ra mức độ chênh lệch mà nó tạo ra là áp dụng cùng một ứng dụng với #define _(x) x
thay vì #define _(x) gettext(x)
và xem bạn có nhận thấy bất kỳ sự khác biệt nào không.
Tôi vẫn nghĩ rằng "phân trang" là một cá trích đỏ. Nếu máy ở dưới áp suất bộ nhớ CAO thì nó sẽ chạy chậm bất kể cái gì (Nếu tôi viết một đoạn mã phân bổ 16GB [Tôi có RAM 16 GB trong máy] trên máy của mình, mọi thứ ngoại trừ chính bàn phím (có thể nhấp nháy đèn num-lock) và con trỏ chuột (có thể di chuyển con trỏ chuột trên màn hình) không phản hồi).
Một chương trình sử dụng 'gettext' đang tạo ra kết quả có thể đọc được của con người. Các chi phí thấp hơn là nó sẽ đưa con người đọc văn bản, vì vậy có thể được coi là không đáng kể. (Điều đó không hoàn toàn đúng, nhưng thực tế, chi phí là _not_ một vấn đề.) –
@JamesKanze chương trình cũng có thể tạo ra các báo cáo dài, hoặc nó có thể gửi email hàng loạt cá nhân, hoặc ... Đó là đầu ra là con người có thể đọc được ngụ ý rằng có một con người xung quanh, và chương trình có thể dừng lại cho đến khi anh/cô ấy đọc xong kết quả. – Chris
@James: Ngay cả một byte bị thiếu duy nhất gây ra lỗi trang sẽ gây ra sự chậm trễ đáng chú ý ngay cả bởi con người. Trong trường hợp cực đoan, nó có thể gây ra sự chậm trễ vài giây nếu đĩa cứng phải được tách ra. Ngoài ra khá nhiều chương trình dòng lệnh được bắt đầu từ các tập lệnh có thể có nghĩa là một chương trình được khởi động/dừng lại hàng nghìn lần. Nhưng điểm thực sự là "nó negleglible" không phải là một câu trả lời cho các câu hỏi vì nó chỉ negleglible trong một số trường hợp. – Robby75