Jakie proste zmiany wprowadziły największe ulepszenia do programów Delphi [closed]

Mam program Delphi 2009, który obsługuje dużo danych i musi być jak najszybszy i nie zużywać zbyt dużo pamięci.

Jakie małe proste wprowadziłeś zmiany w kodzie Delphi, które miały największy wpływ na wydajność Twojego programu poprzez zauważalne skrócenie czasu wykonania lub zużycia pamięci?


Dziękuję wszystkim za wszystkie odpowiedzi. Wiele wspaniałych wskazówek.

Dla kompletności zamieszczę kilka ważnych artykułów na temat optymalizacji Delphi, które znaleziono.

Zanim zaczniesz optymalizować Kod Delphi w About.com

Prędkość i rozmiar: Top 10 trików również na About.com

Podstawy optymalizacji kodu i Delphi Optimization Guidelines w Delphi o wysokiej wydajności, odnoszące się do Delphi 7, ale nadal bardzo istotne.

Author: lkessler, 2008-12-17

30 answers

Największa poprawa nastąpiła, gdy zacząłem używać AsyncCalls do konwersji jednowątkowych aplikacji, które używane do zamrożenia interfejsu użytkownika, w (rodzaj) wielowątkowych aplikacji.

Chociaż AsyncCalls może zrobić o wiele więcej, uważam, że jest przydatny do tego bardzo prostego celu. Załóżmy, że masz zablokowany podprogram w następujący sposób: Wyłącz przycisk, Wykonaj pracę, Włącz Przycisk. Przenosisz część 'Do Work' do funkcji lokalnej (nazwij ją AsyncDoWork) i dodajesz cztery linijki kodu:

var  a: IAsyncCall;    
a := LocalAsyncCall(@AsyncDoWork);  
while (NOT a.Finished) do 
  application.ProcessMessages;  
a.Sync;

Co to does for you jest uruchamiany AsyncDoWork w osobnym wątku, podczas gdy główny wątek pozostaje dostępny, aby odpowiedzieć na interfejs użytkownika (jak przeciąganie okna lub kliknięcie przerwania.) Po zakończeniu AsyncDoWork kod jest kontynuowany. Ponieważ przeniosłem go do funkcji lokalnej, wszystkie lokalne var są dostępne, a kod nie musi być zmieniany.

Jest to bardzo ograniczony Typ "wielowątkowości". W szczególności jest to podwójny gwint. Musisz upewnić się, że funkcja asynchroniczna i interfejs użytkownika nie mają dostępu do te same komponenty VCL lub struktury danych. (Wyłączam wszystkie kontrolki z wyjątkiem przycisku stop.)

Nie używam tego do pisania nowych programów. To po prostu bardzo szybki i łatwy sposób, aby stare programy były bardziej responsywne.

 6
Author: Guy Gordon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-03 20:30:17

.BeginUpdate;

.EndUpdate;

;)

 31
Author: moobaa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-17 03:01:31

Użyj narzędzia do profilowania Delphi (Niektóre tutaj lub Tutaj) i odkryj własne szyjki butelki. Optymalizacja niewłaściwych wąskich gardeł to strata czasu. Innymi słowy, jeśli zastosujesz wszystkie te sugestie tutaj, ale zignorujesz fakt, że ktoś umieścił sleep (1000) (lub podobne) w jakimś bardzo ważnym kodzie, to strata twojego czasu. najpierw napraw swoje wąskie gardła.

 22
Author: Jim McKeeth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:09:17

Przestań używać TStringList do wszystkiego.

TStringList to NIE Struktura danych ogólnego przeznaczenia do efektywnego przechowywania i obsługi wszystkiego, od prostych do złożonych typów. Szukaj alternatyw. Używam kontenera Delphi oraz biblioteki algorytmów (DeCAL, dawniej SDL). Julians EZDSL również powinien być dobrą alternatywą.

 20
Author: Vegar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-17 10:38:18

Wstępnie przydzielanie list i tablic, zamiast powiększać je przy każdej iteracji.

To chyba miało dla mnie największy wpływ pod względem prędkości.

 18
Author: Argalatyr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-17 02:13:27

Jeśli potrzebujesz użyć aplikacji.processmesssages (lub podobne) w pętli, spróbuj wywołać ją tylko co N-ta iteracja.

Podobnie, Jeśli aktualizujesz pasek postępu, nie aktualizuj go co iterację. Zamiast tego zwiększaj je o jednostki x CO iteracje x lub skaluj aktualizacje zgodnie z czasem lub jako procent całkowitej długości zadania.

 12
Author: Argalatyr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-17 02:59:20
  1. FastMM
  2. FastCode (lib)
  3. używaj wysokowydajnych struktur danych, takich jak tablica hash (etc). W wielu miejscach szybciej jest utworzyć jedną pętlę, która tworzy tabelę hashową dla Twoich danych. Używa dość dużo pamięci, ale na pewno jest szybki. (może to jest najważniejsze, ale 2 pierwsze są martwe proste i wymagają bardzo niewiele wysiłku)
 9
Author: Tommi Prami,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-17 06:39:35

Zmniejsz operacje na dysku. Jeśli jest wystarczająco dużo pamięci, Załaduj plik całkowicie DO PAMIĘCI RAM i wykonaj wszystkie operacje w pamięci.

 8
Author: samir105,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-17 08:55:56

Rozważ ostrożne użycie wątków. Jeśli nie używasz teraz wątków, rozważ dodanie kilku. Jeśli tak, upewnij się, że nie używasz zbyt wielu. Jeśli korzystasz z komputera z dwoma lub czterordzeniowymi rdzeniami (których większość jest już dostępna), odpowiednie strojenie wątków jest bardzo ważne.

Możesz zajrzeć do Biblioteki OmniThread by Gabr, ale istnieje wiele bibliotek wątków w rozwoju dla Delphi. Możesz łatwo zaimplementować własną równoległość do korzystania z anonimowych typy.

 7
Author: Jim McKeeth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-17 06:30:28

Zanim cokolwiek zrobisz, zidentyfikuj wolne części. Nie dotykaj kodu roboczego, który działa wystarczająco szybko.

 7
Author: Harriv,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-17 07:02:25

Podczas pracy z tstringlist (lub podobnym), Ustaw "sorted: = false" do czasu, gdy będzie potrzebne (jeśli w ogóle). Nie ma się nad czym zastanawiać...

 5
Author: Argalatyr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-17 02:28:31
  1. tworzenie testów jednostkowych
  2. weryfikacja testów all pass
  3. Profil aplikacji
  4. Refaktor szukający wąskich gardeł i pamięci
  5. powtórz z Kroku 2 (w porównaniu do poprzedniego przebiegu)
 5
Author: Jim McKeeth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-17 06:26:07

Inteligentnie używać SetLength () dla łańcuchów i tablic. Zoptymalizuj inicjalizację za pomocą FillChar lub ZeroMemory.

Zmienne lokalne tworzone na stosie (np. typy rekordów) są szybsze niż zmienne przydzielane stercie (objects i New ()).

Używaj ponownie obiektów zamiast niszczyć, a następnie twórz. Ale upewnij się, że kod zarządzania dla tego jest szybszy niż Menedżer pamięci!

 5
Author: Gerry Coll,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-20 00:08:33

Sprawdź mocno używane pętle pod kątem obliczeń, które mogą być (przynajmniej częściowo) wstępnie obliczone lub obsługiwane za pomocą tabeli wyszukiwania. Funkcje Tryg są klasyczne dla tego, ale dotyczy to wielu innych.

 4
Author: Argalatyr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-17 02:56:13

Jeśli masz listę, użyj dynamicznej tablicy czegokolwiek, nawet rekordu w następujący sposób:

To nie wymaga klas, nie wymaga uwalniania, a dostęp do niego jest bardzo szybki. Nawet jeśli musi rosnąć, możesz to zrobić - patrz poniżej. Używaj tylko TList lub TStringList, jeśli potrzebujesz dużej elastyczności zmiany rozmiaru.

type
  TMyRec = record
    SomeString : string;
    SomeValue : double;
  end;

var
  Data : array of TMyRec;
  I : integer;

..begin
  SetLength( Data, 100 ); // defines the length and CLEARS ALL DATA
  Data[32].SomeString := 'Hello';
  ShowMessage( Data[32] );

  // Grow the list by 1 item.
  I := Length( Data );
  SetLength( Data, I+1 );

..end;
 4
Author: Brian Frost,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-29 17:46:29

Oddzielenie logiki programu od interfejsu użytkownika, refaktoryzacja, a następnie optymalizacja najczęściej używanych, najbardziej zasobochłonnych elementów niezależnie.

 3
Author: Argalatyr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-17 02:10:09
  • Wyłącz debugowanie

  • Włącz optymalizacje

  • Usuń wszystkie odniesienia do jednostek, które nie używasz

  • Szukaj wycieków pamięci

 2
Author: Maltrap,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-17 02:12:10

Używaj wielu twierdzeń do debugowania, a następnie wyłącz je w kodzie wysyłki.

 2
Author: Jim McKeeth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-17 06:07:20

Wyłącz sprawdzanie zasięgu i przepełnienia po dokładnym przetestowaniu.

 2
Author: Jim McKeeth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-17 06:07:55

Użyj pełnego FastMM i przestudiuj dokumentację i źródło i sprawdź, czy możesz dostosować je do swoich specyfikacji.

 2
Author: Jim McKeeth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-17 06:13:11

Dla starego rozwoju BDE kiedy zaczynałem Delphi, używałem wielu TQuery komponentów. Ktoś kazał mi użyć TTable master-detail po tym, jak wyjaśniłem mu, co robię, a to sprawiło, że program działał znacznie szybciej.

Wywołanie DisableControls może pominąć niepotrzebne aktualizacje interfejsu użytkownika.

 2
Author: Eugene Yokota,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-17 06:34:23

Podczas identyfikacji rekordów, użyj liczb całkowitych, jeśli w ogóle jest to możliwe do porównania rekordów. Chociaż klucz podstawowy "Nazwa firmy" może wydawać się logiczny, czas spędzony na generowaniu i przechowywaniu tego skrótu znacznie poprawi ogólny czas wyszukiwania.

 2
Author: skamradt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-17 13:17:54

Jeśli naprawdę, naprawdę, naprawdę musisz być lekki, możesz zrzucić VCL. Spójrz na KOL & MCK . Przyznam, że jeśli to zrobisz, handlujesz funkcjami o zmniejszonej powierzchni.

 1
Author: Jim McKeeth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-17 06:09:33

Możesz rozważyć użycie pakietów runtime. Może to zmniejszyć nakład pamięci, jeśli działa więcej niż jeden program, który jest napisany przy użyciu tych samych pakietów.

 1
Author: Jim McKeeth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-17 06:22:51

Jeśli używasz wątków, ustaw ich powinowactwo do procesora. Jeśli nie używasz jeszcze wątków, rozważ ich użycie lub przyjrzyj się asynchronicznym portom we/wy (porty zakończenia), jeśli Twoja aplikacja wykonuje wiele We/Wy.

 1
Author: mghie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-17 12:00:44

Zastanów się, czy baza danych DBMS jest naprawdę idealnym wyborem. Jeśli tylko czytasz Dane i nigdy ich nie zmieniasz, wtedy płaski plik o stałym rekordzie może działać szybciej, zwłaszcza jeśli ścieżka do danych może być łatwo zmapowana (tj. jeden indeks). Trywialne wyszukiwanie binarne w pliku ze stałym rekordem jest nadal niezwykle szybkie.

 1
Author: skamradt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-17 13:11:39
  • BeginUpdate ... EndUpdate
  • ShortString vs. String
  • Użyj tablic zamiast TStrings i TList

Ale smutna odpowiedź jest taka, że tuning i optymalizacja da Ci Może 10% poprawy (i jest to niebezpieczne); re-design może dać ci 90%. Kiedy już naprawdę zrozumiesz cel, często możesz ponownie opisać problem (a zatem rozwiązanie) w znacznie lepszych kategoriach.

Cheers

 1
Author: Richard Haven,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-18 21:44:36

Zbadaj wszystkie pętle i poszukaj sposobów na zwarcie. Jeśli szukasz czegoś konkretnego i znajdziesz go w pętli, użyj polecenia BREAK, aby natychmiast bail...no wyczuj zapętlenie przez resztę. Jeśli wiesz, że nie masz dopasowania, użyj Kontynuuj tak szybko, jak to możliwe.

 1
Author: skamradt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-21 16:10:07

Skorzystaj z kodu projektu FastCode. Części zostały włączone do VCL / RTL WŁAŚCIWEGO( jak FastMM był), ale jest więcej tam można użyć!

Uwaga, mają nową stronę też się przenoszą, ale wydaje się być trochę nieaktywna.

 0
Author: Jim McKeeth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-17 06:16:10

Rozważ problemy ze sprzętem. Jeśli naprawdę potrzebujesz wydajności, rozważ rodzaj dysku twardego(dysków twardych), na którym działa twój program i bazy danych. Istnieje wiele zmiennych, zwłaszcza jeśli prowadzisz bazę danych. RAID też nie zawsze jest najlepszą odpowiedzią.

 0
Author: Jim McKeeth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-17 06:24:12