Сравнительный анализ скорости создания INI-файла в Delphi 12 Update 1 на 32-битных и 64-битных версиях Windows: откуда берется разница в производительности?
Проблема: замедление работы TIniFile на Windows 10 64-bit
Недавно пользователь Jean_D обнаружил интересную проблему при работе с компонентом TIniFile в Delphi 12 Update 1. При создании INI-файла с 6 секциями и 45 ключами в каждой на 32-битной версии Windows операция занимала менее 200 мс, тогда как на Windows 10 64-bit то же самое приложение работало почти 3 секунды — в 15 раз медленнее!
Вот исходный код, вызывающий проблему:
procedure TForm1.Button1Click(Sender: TObject);
var
iCnt: Byte;
iCpt: Byte;
iSection: String;
iIniFile: TIniFile;
iIdentifier: String;
begin
iIniFile := TIniFile.Create(ChangeFileExt(Application.ExeName, '.ini'));
for iCnt := 1 to 6 do
begin
iSection := 'Tab #' + IntToStr(iCnt);
for iCpt := 1 to 45 do
begin
iIdentifier := 'Key #' + IntToStr(iCpt);
iIniFile.WriteInteger(iSection, iIdentifier, Random(999));
end;
end;
iIniFile.Free;
end;
Причины проблемы
Антивирусное ПО: Как выяснилось, основной причиной замедления был Microsoft Defender Antivirus. После его отключения или добавления исключения для папки с данными производительность возвращалась к нормальным значениям.
Разная обработка вызовов API: Как отметил Stefan Glienke, TIniFile использует WritePrivateProfileString для каждой записи, что может вызывать дополнительные проверки со стороны антивируса.
Предвзятость к компиляторам: Любопытно, что аналогичный код на C++ (использующий те же API-функции) не испытывал таких проблем с производительностью, что наводит на мысли о разном уровне доверия к приложениям, скомпилированным разными компиляторами.
Решения и оптимизации
1. Использование TMemIniFile
Как предложил Remy Lebeau, замена TIniFile на TMemIniFile кардинально улучшает производительность — до 5 мс!
procedure TForm1.Button1Click(Sender: TObject);
var
iIniFile: TMemIniFile;
// остальные переменные те же
begin
iIniFile := TMemIniFile.Create(ChangeFileExt(Application.ExeName, '.ini'));
// остальной код без изменений
iIniFile.Free;
end;
TMemIniFile работает быстрее, потому что: - Все операции происходят в памяти - Запись на диск происходит один раз при уничтожении объекта - Нет множественных вызовов API для каждой записи
2. Альтернативные методы работы с INI
a) Пакетная запись
procedure TForm1.Button1Click(Sender: TObject);
var
slIni: TStringList;
i, j: Integer;
begin
slIni := TStringList.Create;
try
for i := 1 to 6 do
begin
slIni.Add(Format('[Tab #%d]', [i]));
for j := 1 to 45 do
slIni.Add(Format('Key #%d=%d', [j, Random(999)]));
slIni.Add(''); // пустая строка между секциями
end;
slIni.SaveToFile(ChangeFileExt(Application.ExeName, '.ini'));
finally
slIni.Free;
end;
end;
b) Использование JSON вместо INI
uses
System.JSON;
procedure TForm1.Button1Click(Sender: TObject);
var
jsonObj: TJSONObject;
i, j: Integer;
sl: TStringList;
begin
jsonObj := TJSONObject.Create;
try
for i := 1 to 6 do
begin
jsonObj.AddPair(Format('Tab_%d', [i]), TJSONObject.Create);
for j := 1 to 45 do
(jsonObj.Values[Format('Tab_%d', [i])] as TJSONObject)
.AddPair(Format('Key_%d', [j]), TJSONNumber.Create(Random(999)));
end;
sl := TStringList.Create;
try
sl.Text := jsonObj.ToJSON;
sl.SaveToFile(ChangeFileExt(Application.ExeName, '.json'));
finally
sl.Free;
end;
finally
jsonObj.Free;
end;
end;
Выводы
Проблема замедления TIniFile на Windows 10 64-bit связана в первую очередь с антивирусными проверками.
Для повышения производительности рекомендуется:
Использовать TMemIniFile вместо TIniFile
Добавить папку с данными в исключения антивируса
Рассмотреть альтернативные форматы хранения конфигурации (JSON, XML)
Разница в скорости между Delphi и C++ может быть связана с разным уровнем доверия антивируса к разным компиляторам.
Оптимизированный код с TMemIniFile — это простое и эффективное решение, которое сохраняет совместимость с существующими INI-файлами, но работает значительно быстрее.
Проблема замедления работы TIniFile на Windows 10 64-bit связана с антивирусными проверками и решается использованием TMemIniFile, добавлением исключений в антивирус или переходом на альтернативные форматы хранения данных.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.