Delphi: вызов функции dll C с помощью отладчика занимает 15 с без отладчика 0,16 с. Зачем?

У меня есть следующие настройки:

  1. Приложение командной строки Delphi, написанное на Delphi XE5 и встроенное в Debug 64-bit.
  2. Библиотека написана в Microsoft Visual Studio 2013 и встроена в 64-разрядную версию.
  3. Приложение командной строки Delphi вызывает функцию в Cll.

Что неожиданно:

  1. При отладке приложения командной строки Delphi в Delphi XE5 IDE вызов функции C dll занимает 15 с.
  2. При запуске того же самого приложения командной строки Delphi напрямую (без IDE, без отладчика) вызов функции C dll занимает 0,16 с.

Исходный код приложения командной строки Delphi:

program DelphiCpplibraryCall;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
Windows;

type
TWork = function(Count : Integer) : Integer; cdecl;
var
Handle : THandle;
Work   : TWork;
Result : Integer;
Freq   : Int64;
Start  : Int64;
Stop   : Int64;
begin
try
Handle := LoadLibraryEx('worker.dll', 0, LOAD_WITH_ALTERED_SEARCH_PATH);
Work := GetProcAddress(Handle, 'work');

QueryPerformanceFrequency(Freq);
QueryPerformanceCounter(Start);
Result := Work(500000);
QueryPerformanceCounter(Stop);
Writeln(Format('Result: %d Time: %.6f s', [Result, (Stop-Start) / Freq]));

FreeLibrary(Handle);

Readln;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.

Исходный код C dll:

#include "worker.h"#include <unordered_map>

class Item
{
public:
Item(const int value = 0) : _value(value) {}
virtual ~Item(void) {}
private:
int _value;
};

int work(int count)
{
typedef std::unordered_map<int, Item> Values;
Values* values = new Values;
int k = 0;
for (size_t i = 0; i < count; i++)
{
(*values)[i] = Item(i);
k++;
}
delete values;
return k;
}

Delphi + C dll soure код: DelphiCpplibraryCall.zip

Сравнение времени выполнения:

  • Первая консоль: при отладке в IDE
  • Вторая консоль: при запуске без IDE

Сравнение времени выполнения

По какой-то причине Delphi Debugger, похоже, сильно замедляет вызов функции Cll, что делает почти невозможной отладку.

Кто-нибудь знает, что может быть причиной этой проблемы или как ее избежать? Большое спасибо.

Редактировать: Теперь я могу подтвердить, что описанное поведение не ограничивается только Delphi IDE и Debugger. Эта проблема также происходит, если я:

  1. Я строю Cll в Microsoft Visual Studio 2013 в выпуске.
  2. И построить и отладить исполняемый файл командной строки, который вызывает C dll в Visual Studio 2013.

Это означает, что время выполнения функции сборки релиза C dll изменяется в зависимости от того, подключен ли отладчик или нет.

Я также могу подтвердить, что это удаление unordered_map (delete values;) это занимает столько времени, как только присутствует отладчик.

8

Решение

Если задержка исходит от delete тогда вызов может быть диспетчером памяти (malloc), который использует диспетчер памяти кучи Windows. Менеджер памяти кучи выполняет дополнительные расширенные проверки, когда освобождается память и подключается отладчик.

Эти дополнительные проверки можно отключить, установив переменную среды _NO_DEBUG_HEAP в 1 (начинается с подчеркивания).

Вы можете сделать это в Delphi для конкретного проекта в Project/Options.../Debugger/Environment Block или вы можете добавить _NO_DEBUG_HEAP в блок окружения пользователя под Control Panel/System Properties/Advanced System Settings/Environment Variables/System Variables так что это работает для всех проектов и всех приложений. Но тогда вам может потребоваться выйти из системы, чтобы применить изменения или хотя бы перезапустить IDE.

Блок среды параметров проекта Delphi

5

Другие решения

Похоже, что это проблема с реализацией MSVC этого контейнера STL. Точно такое же поведение можно увидеть при использовании отладчика Visual Studio. Среда выполнения MSVC переключает поведение при обнаружении отладчика.

Я нашел следующие ссылки, связанные с этой проблемой:

Большая часть проблемы, по-видимому, связана с производительностью при очистке карты. Просто удалите delete линия из вашего кода C ++, чтобы увидеть значительно улучшенную производительность.

Я не могу найти способ обойти эту проблему.

3

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector