2009-02-26 16 views
5

Dziś miałem za zadanie poprawić wydajność klasycznej strony ASP. Przepisanie kodu w ASP.NET nie jest w tej chwili opcją, więc podjąłem wyzwanie, by wycisnąć każdą uncję wydajności, którą mogę wydostać się ze strony.Wskazówki dotyczące wydajności dla klasycznego bolusa?

Strona składa się z podstawowego "SELECT bla bla FROM bla" na kilka zestawów rekordów. Pętla while iteruje przez te zestawy rekordów i zrzuca strun. W pętli while znajduje się szereg warunków warunkowych i inne. Istnieją 3 wywoływane podprogramy, które używają zmiennych globalnych (nie zmienne lokalne przekazywane jako parametry).

Nic tak naprawdę nie jest szokujące ani nic. Zanim rozpocząłem optymalizację, wykonanie pętli zajęło około 15 sekund. Z 15 sekund do 6 zajęło zapytanie sql.

Po zmianie kilku rzeczy udało mi się uzyskać około 7 sekund.

rzeczy, które zmieniły wokół są:

  • Zamiast robić SELECT * wybrałem tylko te kolumny, które potrzebne. Zapytanie trwało średnio 4 sekundy. To dość ciężkie zapytanie z widokami w widokach.

  • Usunąłem wszystkie przełączanie kontekstu w pętli. Zmieniłem rzeczy takie jak <% = bla%> na Response.Write (bla).

  • 3 podprogramy zostały zdefiniowane jako funkcje, ale zostały użyte jako podrzędne (bez wyniku). Więc zmieniłem funkcje na subs. To pomaga?

Po wprowadzeniu zmian stwierdziłem, że większość czasu została podjęta przez jeden z podprogramów. Nie miałem czasu na tyle szeroki, aby zmienić podprogram, ale składa się z rzeczy, takich jak:

  • data funkcji: DateAdd, DateDiff
  • funkcje tablicy: Ubound (ARR) oraz indeks bazowania: arr (I)
  • funkcje łańcuchowe: lewo, mID, prawy, dolny, zastąpić

Przy każdym wywołaniu strony, że podprogram jest 1600 razy biegać.

Ktoś ma jakieś doświadczenia z optymalizacją klasycznych stron asp? Czy masz jakieś dobre wskazówki dotyczące optymalizacji? To, czego szukam, to poprawa kodu wewnątrz instrukcji pętli do ...

Jestem doświadczonym programistą ASP.NET i wiem trochę o poprawie wydajności w ASP.NET. Klasyczna ASP używa innego "silnika", więc zastanawiałem się, czy ktokolwiek ma wgląd w poprawę wydajności klasycznej ASP.

Dzięki!

M

PS: Tak wiem, że klasyczny ASP używa VBScript

Odpowiedz

3

Przy każdym wywołaniu strony, że podprogram jest 1600 razy biegać.

Powiedziałbym, że to dość dużo cały problem, ale nie znając szczegółów danych powrócił do zapytania, co to podprogram i dlaczego to musi być zrobione 1600 razy na stronie, to Trudno zasugerować wiele, aby ją obniżyć.

+0

Jest to aplikacja do planowania, a osoba, która go zbudowała, entuzjastycznie stworzyła pętlę o dużej długości, która pokazuje planowanie wielu rekordów na cały miesiąc (30 kolumn i około 20 wierszy). – mghaoui

0

Jeśli naprawdę uważasz, że problem dotyczy tej 1 funkcji, dlaczego nie wstawisz tutaj kodu, aby ludzie mogli wysyłać sugestie optymalizacji.

+0

Niestety nie jestem właścicielem kodu. Pewnie wpadnę w kłopoty z opublikowaniem tego. Funkcja w zasadzie buduje łańcuchy na podstawie zestawu rekordów, ale łączy i konwertuje, a następnie opróżnia go za pomocą response.write. Standardowe rzeczy. – mghaoui

+0

Niestety, trudno jest podać sugestie, kiedy robisz standardowe rzeczy i nie mamy dostępu do kodu. :) Tak jak powiedział Chad, może lepiej pomyślisz o "dlaczego". A może możesz spróbować przenieść kilka operacji do procedury przechowywanej. –

+0

Zastanawiam się, czy to właśnie konkatenacja powoduje problem. VB jest znany z tego, że nie obsługuje poprawnie ciągów znaków ... Sprawdź alternatywną metodę zapisu na ekranie lub tworzenia długich ciągów znaków (tablica myśli lub obiekt strumienia). –

-2

Doświadczyłem, że w większości przypadków można uzyskać wydajność podczas korzystania z StringBuilder w klasycznej ASP. Jest ładny StringBuilder implementation dla klasycznej ASP w ramach ajaxed library. Korzysta z .NET StringBuilder. To jest bardzo fajne i łatwe w użyciu:

<% 
set output = new StringBuilder 
do 
    output("some output") 
loop 
response.write(output.toString()) 
%> 

Polecam korzystanie z biblioteki ajaxed, jeśli chcesz zrobić jakieś poprawki. Jest szybko skonfigurowany i oferuje wiele narzędzi do klasycznego ASP. Na przykład. Być może możesz również uzyskać trochę wydajności podczas korzystania z AJAX (lub przynajmniej wrażenie wydajności).

3

Zaznaczam odpowiedź MrChrister jako odpowiedź na moje pytanie "Czy masz jakieś dobre wskazówki dotyczące optymalizacji?". Wskazówki są dobre i udało się przyspieszyć skrypt o 2 sekundy.

Dowiedziałem się, co było przyczyną powolnego pisania scenariusza. W pętli while programator robił dużo filtrów (Array). Zasadniczo używał funkcji Filter (Array) do wyszukiwania par klucz/wartość.

Ostatecznym rozwiązaniem było zmienienie kodu filtra (macierz) na obiekt "Scripting.Dictionary". To przyspieszyło kod o współczynnik 12.

Dziękuję za wszystkie odpowiedzi.

M

3

Widząc, że jest to popularne pytanie Zdecydowałem się wyjaśnić co zrobiłem 3 lata temu, że przyspieszyło skryptu ASP.

Oryginalny skrypt mocno wykorzystywał zmienne tablice do przechowywania par klucz-wartość, więc zmodyfikowałem ten kod, aby używać Scriting.Dictionary. Przykład:

Dim myDictionary 
Set myDictionary = Createobject("Scripting.Dictionary") 
myDictionary.item("key") = "value" 

To o wiele szybsze niż zmienne tablice.

Kolejną dużą zmianą jest konkatenacja ciągów. Oryginalny scenariusz był pełen:

S = "" 
S = S & "First line<br />" 
S = S & "Second line<br />" 
S = S & "Third line line<br />" 
Response.Write(S) 

zmodyfikowałem to:

Response.Write("First line<br />") 
Response.Write("Second line<br />") 
Response.Write("Third line<br />") 

To sprawiło ogromną różnicę. Łączenie łańcuchów jest ogromnym wąskim gardłem, ponieważ sznur jest wyrzucany, a następnie reinicjowany.

Inną opcją jest:

S = "First line<br />" & _ 
     "Second line<br />" & _ 
     "Third line line<br />" 
Response.Write(S) 

Jest to również dobra wskazówka dla ASP.NET: Użyj StringBuilder zamiast konkatenacji ciągów.

Kolejną ważną zmianą jest przełączanie kontekstów. Oryginalny kod był pełen: Przełączniki

<table> 
    <tr> 
     <td><%= rs("Col1") %></td> 
     <td><%= rs("Col2") %></td> 
     <td><%= rs("Col2") %></td> 
    </tr> 
</table> 

Kontekst 3 zająć dużo czasu, więc zmodyfikowany do tego:

<% 
Response.Write("<table>") 
Response.Write("<tr>") 
Response.Write("<td>") 
Response.Write(rs("Col1")) 
Response.Write("</td>") 
Response.Write("</tr>") 
Response.Write("<tr>") 
Response.Write("<td>") 
Response.Write(rs("Col2")) 
Response.Write("</td>") 
Response.Write("</tr>") 
Response.Write("<tr>") 
Response.Write("<td>") 
Response.Write(rs("Col3")) 
Response.Write("</td>") 
Response.Write("</tr>") 
Response.Write("</table>") 
%> 

Tak Kod jest bardzo zbędny ale wykonuje lepiej.

Kolejna mała zmiana (co jest rzeczywiście brudne Hack) jest w użyciu (NOLOCK) w zapytaniach SQL:

conn.Query("SELECT * FROM MyTable WITH (NOLOCK) LEFT JOIN AnotherTable WITH (NOLOCK) ON MyTable.Id = AnotherTable.Id") 

To robi różnicę.

Wreszcie, nie wiem, czy to bardzo pomaga, ale było dużo kopiowanego kodu, który przełożyłem na czyste funkcje.

Mam nadzieję, że osoby, które znajdą ten produkt, uznają te porady za przydatne.

+0

Mój komentarz został oceniony na 0? Naprawdę? Czy osoba, która potwierdziła wniosek, rzeczywiście przeczytała wątek? – mghaoui

Powiązane problemy