2012-07-12 12 views
7

TłoCzy sposób, w jaki tłumaczymy naszą stronę skutkuje problemami z wydajnością?

Nasza strona jest stroną prasową i jest oglądana przez wiele osób na całym świecie. Oczywiście oznacza to, że będziemy lokalizować stronę w jak największej liczbie języków. Profesjonalny tłumacz zostanie zatrudniony dla każdego języka.

Jak nasza strona działa obecnie

Sposób Zaplanowaliśmy to zrobić poprzez przechowywanie tłumaczenie każdego elementu strony w bazie danych połączonej przez GUID. Więc kiedy strona ładuje ciągi są wyciągane z bazy danych za pomocą Guid i preferencji językowych użytkownika.

Mamy kilka dokumentów w naszym projekcie, które zawierają tłumaczenia angielskie. Takie jak ten:

public class StandardButtonToken : LocalisationToken 
{ 
    protected StandardButtonToken(string defaultText, Guid key) : base(defaultText, key) 
    { 
    } 

    public static readonly LocalisationToken Update = new StandardButtonToken("Update", Guid.Parse("8a999f5b-7ca1-466d-93ca-377321e6de00")); 
    public static readonly LocalisationToken Go = new StandardButtonToken("Go", Guid.Parse("7a013ecc-0772-4f87-9f1f-da6a878a3c99")); 
    public static readonly LocalisationToken Edit = new StandardButtonToken("Edit", Guid.Parse("c31be427-5016-475d-997a-96fa5ff8b51f")); 
    public static readonly LocalisationToken New = new StandardButtonToken("New", Guid.Parse("f72d365c-b18f-4f01-a6e4-b0cd930dc730")); 
    public static readonly LocalisationToken More = new StandardButtonToken("More", Guid.Parse("bd4da7df-afd2-481e-b6b6-b4a989324758")); 
    public static readonly LocalisationToken Delete = new StandardButtonToken("Delete", Guid.Parse("ab00ec14-4414-4cda-a8e2-4f03c9e7c5a8")); 
    public static readonly LocalisationToken Add = new StandardButtonToken("Add", Guid.Parse("01e44600-a556-4a07-8a2a-e69a1ea79629")); 
    public static readonly LocalisationToken Confirm = new StandardButtonToken("Confirm", Guid.Parse("4c50e91e-3e2f-42fa-97aa-9f1f6f077f09")); 
    public static readonly LocalisationToken Send = new StandardButtonToken("Send", Guid.Parse("24121766-f424-4d73-ac58-76f90d58b95c")); 
    public static readonly LocalisationToken Continue = new StandardButtonToken("Continue", Guid.Parse("dd2ca0e5-8a35-4128-b2e8-db68a64a6fe5")); 
    public static readonly LocalisationToken OK = new StandardButtonToken("OK", Guid.Parse("9a359f93-7c23-44ad-b863-e53c5eadce90")); 
    public static readonly LocalisationToken Accept = new StandardButtonToken("Accept", Guid.Parse("3206a76b-1cd7-4dc3-9fff-61dfb0992c75")); 
    public static readonly LocalisationToken Reject = new StandardButtonToken("Reject", Guid.Parse("f99c6a9c-6a55-4f55-ac4b-9581e56d18d3")); 
    public static readonly LocalisationToken RequestMoreInfo = new StandardButtonToken("Request more info", Guid.Parse("19f3d76b-dafa-47ae-8416-b7d61546b03d")); 
    public static readonly LocalisationToken Cancel = new StandardButtonToken("Cancel", Guid.Parse("75617287-5418-466b-9373-cc36f8298859")); 
    public static readonly LocalisationToken Publish = new StandardButtonToken("Publish", Guid.Parse("efd87fd4-e7f1-4071-9d26-a622320c366b")); 
    public static readonly LocalisationToken Remove = new StandardButtonToken("Remove", Guid.Parse("f7db5d81-5af8-42bf-990f-778df609948e")); 
} 

każdym razem utworzyć stronę mamy pewność przyciski używać tych tokenów zamiast ręcznie wpisywać tekst. Jeśli zdecydujemy, że potrzebujemy nowego przycisku, dodamy nowy token w poniższym pliku, a po uruchomieniu witryny po raz pierwszy sprawdzi, czy istnieje w bazie danych, a jeśli nie, zostanie utworzony.

Więc jeśli chodzi o tłumaczenie, wyślemy te tokeny tłumaczom, a one zmienią tylko tekst. Zostanie on następnie dodany do witryny w odpowiednim języku, a strona wywoła poprawne tłumaczenie w zależności od wybranego języka.

problem/pytanie

Nasze tokeny kursowe mają domyślny tekst jako ciągi znaków, ale obawiam się, że serwer musi załadować wszystkie z tych ciągów tekstowych w pamięci przy rozruchu. W rzeczywistości są one używane tylko do przechowywania tłumaczenia w bazie danych i nigdy nie są używane w kodzie, więc uważam, że może to być trochę marnotrawstwem. Zamiast tego uważam, że moglibyśmy wywoływać te tłumaczenia osobno, gdy jest to wymagane, być może z jakiegoś rodzaju tablicy przeglądowej, która nie jest w pamięci.

Pytanie brzmi. Czy sposób, w jaki obecnie to robimy spowoduje problemy z wydajnością?

Jeśli tak, to czy ktoś może zaproponować lepsze rozwiązania?

Łącznie na naszej stronie znajduje się 1000 tokenów.

Google nie był dla mnie bardzo pomocny przy tej okazji, więc wszelkie rady byłyby mile widziane. Starałem się tak mocno, jak to możliwe, aby to powiedzieć, aby miało to sens. Nie jest to łatwe do wyjaśnienia.

Z góry dziękujemy za pomoc, jakiej mogą udzielić ludzie.

+2

dlaczego nie spróbować użyć zasobów ** ** pliki ... zobacz (http://msdn.microsoft.com/en-us/magazine/cc163566.aspx) – Yasser

+0

Niestety pliki zasobów nie są możliwe jako Musimy być w stanie zmieniać rzeczy w locie i nie musimy rekompilować. –

+0

jak rozumiem po wat czytałem ... potrzebujesz lokalizacji dla przycisków w prawo? – Yasser

Odpowiedz

3

Obecnie pracuję z zespołem nad projektem, w którym mieliśmy podobną sytuację. Nasz projekt to aplikacja oparta na klientach/serwerach. Baza danych z naszymi tłumaczeniami spoczywa na serwerze, a wszystkie nasze kontrolki mają domyślne wartości angielskie. Oryginalnie po otwarciu nowego okna odczytaliśmy bazę danych i wyciągnęliśmy potrzebne tłumaczenia oraz przetłumaczyliśmy formanty. W ten sposób tylko wartości, które potrzebowaliśmy, tłumaczone były w pamięci i tylko tak długo, jak wymagało tego okno. Gdy okno zostanie zamknięte, pamięć zostanie odzyskana za pomocą garbage collection.

Odkryliśmy, że nawet przy wszystkich tłumaczeniach każdego przycisku, etykiety, nagłówka kolumny, itd. ... cały system został załadowany do pamięci, gdzie mamy do czynienia tylko z parąset K. W końcu to, co zrobiliśmy było:

  1. użytkownik loguje się na:
    • jeśli domyślnie innego języka poza angielskim tabela danych jest ustawiony w pamięci i wypełniona tłumaczenia z wszystkich formantów użytkownika w naszym systemie z serwera.
    • Ta tabela danych ma klucz podstawowy, aby pomóc w ulepszeniu zapytań przeciwko niemu. Dopóki aplikacja jest otwarta, ta tabela danych istnieje.
    • Za każdym razem, gdy tworzona jest kontrola użytkownika, uruchamiana jest metoda, która wyszukuje tłumaczenie i stosuje je.

czasu zajęło się zalogować użytkownik nie wzrost, ale tylko przez kilka milisekund średnio.

Mimo wszystko to zastanawiam się, czy można użyć podobną konstrukcję. Pomysł ten sprawiłby, że serwer nie musiałby śledzić tłumaczeń na sesję. Po prostu nakieruje stronę na użytkownika.

  1. użytkownik loguje się:
    • DataTable obiektu jest wypełniona wszystkich tłumaczeń dla danego terenu
    • WriteXML() jest wywoływana
    • otrzymany XML jest wysyłany do klienta
  2. Kiedy użytkownik przechodzi do nowej strony:
    • skrypt po stronie klienta jest wywoływana, który korzysta z XML przetłumaczyć stronę na komputerze klienta.

Można dodać trochę buforowanie tak, że XML jest wymieniana tylko wtedy, gdy strona jest aktualizowana lub może po prostu nie każdy użytkownik pobranie XML za każdym razem przy logowaniu. Tak czy inaczej, ładuje się z serwera.

+0

Ciekawa opcja, będę się nad tym zastanawiać, dziękuję Chris! –

+0

Chociaż nie zdecydowałem, czy użyć tej odpowiedzi, jest to najlepsze z nich, a zatem możesz mieć nagrodę. –

3

Ignorując inne implementacje i koncentrując się na konfiguracji, której używasz, odpowiedź brzmi "tak" i "nie".

Tak, mogą występować problemy z wydajnością z metodą, którą stosujesz, jeśli liczba żądań przychodzących rośnie, a zwłaszcza wraz ze wzrostem liczby tokenów. Ta relacja może być łatwo wyjaśniona jako "im więcej żądań, tym więcej pracy musi wykonać serwer." Więcej żetonów, które istnieją, tym więcej pracy musi wykonać serwer. Jeśli zarówno żądania, jak i żetony wzrosną, wybuchasz ilość pracy, jaką musi wykonać serwer."

" Nie "może zostać osiągnięte poprzez dodanie do obecnego rozwiązania. Możesz dodać pamięć podręczną do konfiguracji, która będzie zapisywać przetłumaczone strony, tak aby serwer nie musiał wysyłać zapytań do bazy danych lub tłumaczyć każdej strony za jednym razem. . żądanie na przykład, jeśli masz jedną stronę mypage.aspx że zawiera 20 przetłumaczenia tokenów - Niech serwer przetłumaczyć go po raz pierwszy, a następnie zapisz plik jako przetłumaczone, powiedzmy, /localized/mypage.EN.html i wszystkie przyszłe żądania (jeśli oryginalna strona nie została zmodyfikowana lub nowe tokeny nie zostały dodane) będą po prostu wysyłane na buforowaną stronę zamiast ponownego tłumaczenia za każdym razem.

Dodatkowo, możesz mieć serwer generować wszystkie tłumaczenia, gdy strona jest aktualizowana lub tokeny są aktualizowane zamiast czekać fo r klient-prośba przyjść.

+0

Cache już działa, więc może to rozwiązanie jest w porządku, po wszystkim –

+0

Jeśli to buforuje, to nie powinno być żadnych problemów z wydajnością - będzie to jednorazowe tłumaczenie (każdy Dodatkowo, jeśli zauważalne opóźnienie w załadowaniu strony, która powinna być już buforowana, problem będzie związany z metodami przetwarzania żądań, a nie z kodem lokalizacji – newfurniturey

+0

Wypróbuj dotTrace, justTrace lub podobny narzędzie do profilowania pamięci, które wskaże ci odpowiedź, a także wskaże metody, które są "gorące" (co oznacza, że ​​musisz pracować nad zwiększeniem wydajności). – turtlepick