Biorąc pod uwagę, że alternatywą dla tego podejścia jest to, aby mieć dużą liczbę od buduje, każdy z czymś takim w nim:
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;
}
zamiast otrzymujemy:
int main()
{
printf(gettext("Hello, World\n"));
}
który jest łatwy do Przeczytaj i zrozum.
Nie znam dokładnej struktury implementacji gettext, ale spodziewam się, że jest to tablica haszująca po załadowaniu. Prawdopodobnie binarne drzewo, ale tablica hash wydaje się bardziej sensowna.
Co do dokładnych kosztów ogólnych, bardzo trudno jest umieścić na nim numer - szczególnie, jak mówisz, jeśli coś jest zamieniane na dysk, a dysk się zatrzymał, potrzeba 3-4 sekund na podniesienie dysku przyspieszyć. Jak oceniasz to? Tak, możliwe, że strona wymagana dla gettext
zostanie zamieniona, jeśli system był zajęty wykonywaniem dużej ilości pamięci.
Ładowanie pliku wiadomości powinno być dużym obciążeniem tylko wtedy, gdy plik jest bardzo duży, ale znowu, jeśli dysk nie obraca się, a plik nie jest buforowany, to będzie narzut kilka sekund. Ponownie, jak to określić. Rozmiar pliku jest wyraźnie wprost proporcjonalny do rzeczywistego rozmiaru przetłumaczonych (lub natywnego języka) wiadomości.
Odnośnie punktu 2:
O ile mi wiadomo, zarówno w systemach Linux i Windows, strony są zamieniane na „najdawniej używane” (lub jakiś inny Wykorzystanie statystycznej) podstawy, która nie ma nic wspólnego z gdzie się znajdują. Oczywiście przetłumaczone wiadomości znajdują się w innym miejscu niż rzeczywisty kod - w pliku źródłowym nie ma listy 15 różnych tłumaczeń, więc tłumaczenia są ładowane w środowisku wykonawczym i będą znajdować się w innym miejscu niż sam kod.Jednakże, narzut ten jest podobny do napowietrznej różnicy między:
static const char *msg = "Hello, World\n";
i
static const char *msg = strdup("Hello, World\n");
Zważywszy, że ciągi tekstowe są na ogół trzymane razem w binarnym programu w każdym razie, nie wiem uważam, że ich "bliskość" kodu wykonującego jest znacząco różna od dynamicznie przydzielonego fragmentu pamięci gdzieś w stercie. Jeśli często będziesz wywoływał funkcję gettext
, pamięć ta będzie zachowywana "aktualna", a nie zamieniana. Jeśli nie zadzwonisz na numer gettext
przez jakiś czas, może zostać zamieniony. Ale odnosi się to do "żadnego z ciągów przechowywanych w pliku wykonywalnym nie użyto ostatnio, więc zostały zamienione".
3) Myślę, że angielski (lub "bez wybranego języka") traktowany jest dokładnie tak samo, jak każdy inny wariant językowy.
będę miał trochę dalej kopać trochę, trzeba pierwsze śniadanie ...
bardzo nienaukowe:
#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);
}
daje następujące wyniki:
$ 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
w kodzie dcigettext.c
używa mieszaniny wyszukiwania binarnego w płaskiej tablicy łańcuchów i funkcji mieszania, która miesza łańcuch z hashami PJW (patrz: http://www.cs.hmc.edu/~geoff/classes/hmc.cs070.200101/homework10/hashfuncs.html).
Tak więc, narzut, po uruchomieniu aplikacji, wydaje się być "zauważalny" (przy zliczaniu cykli zegara), ale niezbyt duży.
Dokładny czas potrzebny na uruchomienie pierwszego sprintf
jest nieco inny w obu przypadkach, więc nie powiedziałbym, że "używanie gettext" przyspiesza sprintf przy pierwszym połączeniu - tylko "pech" w tym biegu (I miał kilka innych wariantów kodu, a wszystkie one różnią się znacznie w pierwszym wywołaniu sprintf
, a mniej w przypadku późniejszych połączeń). Prawdopodobnie niektóre ustawienia (prawdopodobnie pamięci podręczne [printf powodujące zastąpienie buforów innymi śmieciami] jest całkiem prawdopodobne], prognozy rozgałęzień itp.) Gdzieś, co zajmuje więcej czasu ...
To oczywiście nie odpowiada na pytania dotyczące stronicowania itp. I nie próbowałem zrobić szwedzkiego, portugalskiego ani niemieckiego tłumaczenia mojego komunikatu "Hello, World". Nadal uważam, że nie jest on ogromny, chyba że faktycznie wykonujesz setki instancji aplikacji na sekundę, a ta aplikacja nie robi nic innego niż wydrukowanie wiadomości na ekranie po wykonaniu prostych obliczeń, na pewno może to być ważne .
Jedynym PRAWDZIWYM sposobem, aby dowiedzieć się, jak dużą różnicę stanowi kompilacja tego samego zastosowania z #define _(x) x
zamiast #define _(x) gettext(x)
i zobacz, czy zauważysz jakąkolwiek różnicę.
Nadal uważam, że "stronicowany" to czerwony śledzia. Jeśli urządzenie znajduje się pod WYSOKIM nadciśnieniem, to będzie ono działało wolno bez względu na to, co (jeśli napiszę kod, który przydziela 16 GB [mam 16 GB pamięci RAM w komputerze] na moim komputerze, prawie wszystko oprócz samej klawiatury (może migać diodą num-lock), a sam wskaźnik myszy (może przesuwać wskaźnik myszy po ekranie) przestaje reagować).
Program wykorzystujący 'gettext' generuje dane wyjściowe czytelne dla człowieka. Narzut jest mniejszy niż potrzeba, aby człowiek przeczytał tekst, więc można go uznać za nieistotny. (To nie jest ściśle prawda, ale realistycznie, obciążenie nie jest problemem.) –
@JamesKanze program może również generować długie raporty lub może wysyłać spersonalizowane wiadomości masowe, lub ... To, że dane wyjściowe można odczytać przez człowieka, nie sugerować, że w pobliżu znajduje się człowiek i że program może przestać działać, dopóki nie skończy czytać wyników. – Chris
@ James: Nawet jeden pojedynczy brakujący bajt, który powoduje błąd strony, spowoduje opóźnienie, które jest zauważalne nawet przez człowieka. W skrajnych przypadkach może powodować opóźnienie o kilka sekund, jeśli dysk twardy musi zostać odwirowany. Z skryptów uruchamianych jest również wiele programów uruchamianych z wiersza poleceń, co może oznaczać, że program jest uruchamiany/zatrzymywany tysiące razy. Ale prawdziwym punktem jest to, że "to jest nie do zniesienia" nie jest odpowiedzią na pytania, ponieważ w niektórych przypadkach jest tylko niepotrzebne. – Robby75