Какие простые изменения делали самые большие улучшения Ваших программ Delphi [закрытыми]

У меня есть программа Delphi 2009 года, которая обрабатывает много данных и должна быть максимально быстро и не использовать слишком много памяти.

Какие небольшие простые изменения Вы внесли в свой код Delphi, который оказал самое большое влияние на производительность Вашей программы путем примечательного сокращения использования памяти или времени выполнения?


Спасибо все для всех Ваших ответов. Много больших подсказок.

Для полноты я отправлю несколько важных статей об оптимизации Delphi, которую я нашел.

Прежде чем Вы начнете оптимизировать код Delphi по About.com

Скорость и Размер: Лучшие 10 Приемов также по About.com

Основные принципы Оптимизации кода и Инструкции по Оптимизации Delphi в Высокопроизводительном Delphi, касаясь Delphi 7, но все еще очень подходящий.

28
задан 5 revs, 2 users 100% 5 September 2013 в 01:28
поделиться

35 ответов

Самое большое улучшение произошло, когда я начал использовать AsyncCalls для преобразования однопоточных приложений, которые раньше замораживали пользовательский интерфейс, в (своего рода) многопоточные приложения.

Хотя AsyncCalls может делать намного больше, я нашел его полезным для этой очень простой цели. Допустим, у вас заблокирована подпрограмма следующим образом: кнопка отключения, работа, кнопка включения. Вы перемещаете часть «Do Work» в локальную функцию (назовите ее AsyncDoWork) и добавляете четыре строки кода:

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

Для вас это запускает AsyncDoWork в отдельном потоке, в то время как ваш основной поток остается доступным для ответа на пользовательский интерфейс (например, перетаскивание окна или нажатие кнопки «Прервать»). Когда AsyncDoWork завершается, код продолжается. Поскольку я переместил его в локальную функцию, все локальные переменные доступны, и код не нужно менять.

Это очень ограниченный тип «многопоточности». В частности, это двухпотоковая передача. Вы должны убедиться, что ваша функция Async и пользовательский интерфейс не имеют доступа к одним и тем же компонентам VCL или структурам данных. (Я отключаю все элементы управления, кроме кнопки остановки.)

Я не использую это для написания новых программ. Это действительно быстрый и простой способ сделать старые программы более отзывчивыми.

6
ответ дан 28 November 2019 в 02:12
поделиться

Если действительно, действительно, действительно необходимо быть легким весом тогда, можно потерять VCL. Смотрите на KOL & MCK. Предоставил, делаете ли Вы это тогда, Вы торгуете функциями уменьшенного места.

1
ответ дан Jim McKeeth 28 November 2019 в 02:12
поделиться

Вы могли бы рассмотреть использование пакетов во время выполнения. Это могло уменьшить Ваш след памяти, если существует более тогда одна программа, работающая, который записан с помощью тех же пакетов.

1
ответ дан Jim McKeeth 28 November 2019 в 02:12
поделиться

Если Вы используете потоки, устанавливаете их привязку процессора. Если Вы еще не используете потоки, рассматриваете использование их или изучаете асинхронный ввод-вывод (порты завершения), если Ваше приложение делает много ввода-вывода.

1
ответ дан mghie 28 November 2019 в 02:12
поделиться
  • BeginUpdate... EndUpdate
  • ShortString по сравнению со Строкой
  • массивы Использования вместо TStrings и TList

, Но печального ответа - то, что настройка и оптимизация даст Вам, возможно, 10%-е улучшение (и это опасно); модернизация может дать Вам 90%. Как только Вы действительно понимаете цель, часто можно вновь заявлять о проблеме (и поэтому решение) в намного лучших терминах.

Аплодисменты

1
ответ дан Richard Haven 28 November 2019 в 02:12
поделиться

Для старой разработки BDE, когда я сначала запустил Дельфи, я использовал много из TQuery компоненты. Кто-то сказал мне использовать TTable основная деталь после того, как я объяснил его, что я делал, и это сделало прогон программы намного быстрее.

Вызов DisableControls может опустить ненужные обновления UI.

2
ответ дан Eugene Yokota 28 November 2019 в 02:12
поделиться

Рассмотрите аппаратные проблемы. Если Вам действительно нужна производительность, тогда рассматривают тип жесткого диска (дисков), на котором работают Ваша программа и Ваши базы данных. Существует много переменных особенно при выполнении базы данных. RAID является не всегда лучшим ответом также.

0
ответ дан Jim McKeeth 28 November 2019 в 02:12
поделиться

Использование полный FastMM и исследование документация и источник и видят, можно ли настроить его к спецификациям.

2
ответ дан Jim McKeeth 28 November 2019 в 02:12
поделиться

Используйте в своих интересах некоторые из код проекта FastCode. Части его были включены в надлежащий VCL/RTL (как FastMM, был), но существует больше там, можно использовать!

Примечание, они имеют новый сайт , они перемещаются также, но это, кажется, немного неактивно.

0
ответ дан Jim McKeeth 28 November 2019 в 02:12
поделиться

Выключите проверку диапазона и проверку переполнения после тестирования экстенсивно.

2
ответ дан Jim McKeeth 28 November 2019 в 02:12
поделиться

Рассмотрите тщательное использование потоков. Если Вы не используете потоки теперь, то рассматриваете добавляющую пару. Если Вы, удостоверьтесь, что Вы не используете слишком многих. Если Вы работаете на Двойном или Четырехъядерном компьютере (который большинство больше), тогда, надлежащая настройка потока очень важна.

Вы могли посмотреть Библиотека OmniThread Gabr, но существует много библиотек потока в разработке для Дельфи. Вы могли легко реализовать свою собственную параллель для использования анонимных типов.

7
ответ дан Jim McKeeth 28 November 2019 в 02:12
поделиться

Прекратите использовать TStringList для всего.

TStringList не общая цель datastructure для эффективного устройства хранения данных и обработки всего от простого до составных типов. Ищите альтернативы. Я использую Контейнер Delphi и Библиотека Алгоритма (ПЕРЕВОДНАЯ КАРТИНКА, раньше известная как SDL). Julians EZDSL должен также быть хорошей альтернативой.

21
ответ дан Vegar 28 November 2019 в 02:12
поделиться

Предварительное выделение списков и массивов, вместо того, чтобы вырастить их с каждым повторением.

Это, вероятно, оказало самое большое влияние для меня с точки зрения скорости.

19
ответ дан Argalatyr 28 November 2019 в 02:12
поделиться

Если необходимо использовать Application.processmesssages (или подобный) в цикле, попытайтесь назвать его только каждым Энным повторением.

Точно так же при обновлении progressbar, не обновляйте его каждое повторение. Вместо этого увеличьте его x единицами каждый x повторения или масштабируйте обновления согласно времени или как процент общей длины задачи.

12
ответ дан Argalatyr 28 November 2019 в 02:12
поделиться
  1. (lib) FastMM
  2. FastCode
  3. высокопроизводительные структуры данных Использования, как хэш-таблица (и т.д.). Много мест это быстрее для создания одного цикла, который делает хэш-таблицу поиска для данных. Использование вполне партия памяти, но это, конечно, быстро. (это, возможно - самое важное, но 2 первых очень просты и нуждаются в очень небольшом количестве усилия сделать)
9
ответ дан Tommi Prami 28 November 2019 в 02:12
поделиться

Уменьшите дисковые операции. Если существует достаточно памяти, загрузите файл полностью в RAM и сделайте все операции в памяти.

8
ответ дан samir105 28 November 2019 в 02:12
поделиться

Используйте много утверждений для отладки, затем выключите их в поставлющемся коде.

2
ответ дан Jim McKeeth 28 November 2019 в 02:12
поделиться

Используйте инструмент Delphi Profiling ([приблизительно 110] здесь или здесь ) и узнайте Ваши собственные горлышки бутылки. Оптимизация неправильных узких мест является пустой тратой времени. Другими словами, если Вы применяете все эти предложения здесь, но игнорируете факт, кто-то поместил , сон (1000) (или подобный) в некотором очень важном коде является пустой тратой Вашего времени. Фиксируют Ваши фактические узкие места сначала.

22
ответ дан 2 revs 28 November 2019 в 02:12
поделиться

Прежде чем Вы сделаете что угодно, определите медленные части. Не касайтесь рабочего кода, который работает достаточно быстро.

7
ответ дан Harriv 28 November 2019 в 02:12
поделиться
  1. Создают модульные тесты
  2. , Проверяют тесты вся передача
  3. Профиль, Ваше приложение
  4. Осуществляет рефакторинг поиск узких мест и памяти
  5. Повторение от Шага 2 (по сравнению с предыдущей передачей)
5
ответ дан Jim McKeeth 28 November 2019 в 02:12
поделиться

Сделайте интеллектуальное использование SetLength () для строк и массивов. Оптимизируйте инициализацию с FillChar или ZeroMemory.

Локальные переменные, созданные на стеке (например, типы записи), являются быстрее, чем выделенная "куча" (объекты и Новыми ()), переменные.

объекты Повторного использования, а не Уничтожают, тогда создают. Но удостоверьтесь, что код управления для этого быстрее, чем диспетчер памяти!

5
ответ дан 4 revs, 2 users 91% 28 November 2019 в 02:12
поделиться

Проверьте используемые в большой степени циклы на вычисления, которые могли быть (по крайней мере, частично) предварительно вычислены или обработаны с таблицей поиска. Аккуратные функции являются классиком для этого, но это относится ко многим другим.

4
ответ дан Argalatyr 28 November 2019 в 02:12
поделиться

Разделение логики программы от пользовательского интерфейса, рефакторинга, затем оптимизируя наиболее используемый, большинство ресурсоемких элементов независимо.

3
ответ дан Argalatyr 28 November 2019 в 02:12
поделиться
  • отладка Поворота ПРОЧЬ

  • оптимизация Поворота ПО телефону

  • Удаляет все ссылки на единицы, которые Вы на самом деле не используете

  • , Ищут утечки памяти

2
ответ дан Maltrap 28 November 2019 в 02:12
поделиться

При работе с tstringlist (или подобный), набор "отсортировал: = ложь", пока не необходимый (если вообще). Походит на легкую задачу...

5
ответ дан Argalatyr 28 November 2019 в 02:12
поделиться

. BeginUpdate;

.EndUpdate;

;)

30
ответ дан moobaa 28 November 2019 в 02:12
поделиться

При идентификации записей используйте целые числа если вообще возможный для рекордного сравнения. В то время как первичный ключ "названия компании" мог бы казаться логичным, время потратило генерацию, и хранение хеша этого значительно улучшит полное время поиска.

2
ответ дан skamradt 28 November 2019 в 02:12
поделиться

Рассмотрите, является ли база данных DBMS действительно отличным выбором. Если Вы только считываете данные и никогда не изменяете их, то плоский фиксированный рекордный файл мог работать быстрее, особенно если путь к данным может быть легко отображен (т.е., один индекс). Тривиальный двоичный поиск на фиксированном рекордном файле все еще чрезвычайно быстр.

1
ответ дан skamradt 28 November 2019 в 02:12
поделиться

Изучить все петли и найти пути к короткому замыканию. Если вы ищете что-то конкретное и нашли его в цикле, то используйте команду BREAK для немедленного освобождения под залог ... бессмысленно проходить через все остальное. Если вы знаете, что у вас нет совпадения, используйте ПРОДОЛЖЕНИЕ как можно быстрее.

1
ответ дан 28 November 2019 в 02:12
поделиться

Если у вас есть список, используйте динамический массив чего угодно, даже следующую запись:

Для этого не нужны классы, нет освобождения и доступа к нему очень быстро. Даже если ему нужно вырасти, вы можете это сделать - см. Ниже. Используйте только TList или TStringList , если вам нужна большая гибкость в изменении размера.

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
ответ дан 28 November 2019 в 02:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: