Форум: "Потрепаться";
Текущий архив: 2003.11.13;
Скачать: [xml.tar.bz2];
ВнизК вопросу об оптимизации при работе с WinAPI Найти похожие ветки
← →
Dima_dvp (2003-10-23 21:54) [0]Возник у меня такой вопрос:
Есть абстрактный такой код:
var
APIRecord: Какая-нибудь структура API
for 1 to MNOGO do begin
Инициализируем APIRecord в зависимости от счётчика цикла
APIFunction(..., адрес APIRECORD);
end;
Но ведь всегда(почти) есть поля этой структуры которые остяются неизменными для всех итераций цикла. Так зачем же их перезаписывать столько раз.
С другой стороны исходя из того что пы передаём адрес - у нас нет гарантии, что APIFunction не изменит APIRecord. Хотя на практике я ещё не видел такого, чтобы она что-то в Записи изменила(если это не предусмотрено), но мне всё-таки интересна степень с которой можно доварять такому коду:
var
APIRecord: Какая-нибудь структура API
Инициализируем часть APIRecord, не заыисящую от счётчика цикла
for 1 to MNOGO do begin
Инициализируем часть APIRecord, зависящую от счётчика цикла
APIFunction(..., адрес APIRECORD);
end;
Если подумать, то в некоторых случаях можно сделать и так, но это уже к вопросу об неэкономии памяти:
var
APIRecord: Какая-нибудь структура API
Инициализируем часть APIRecord, не заыисящую от счётчика цикла
for 1 to MNOGO do begin
Инициализируем часть APIRecord, зависящую от счётчика цикла
if (not APIFunction(..., адрес APIRECORD)) then begin
Инициализируем APIRecord понлностью в зависимости от счётчика цикла
APIFunction(..., адрес APIRECORD);
end;
end;
так где же та самая Золотая середина. Или вообще нельзя доверять WinAPI???
← →
Rouse_ (2003-10-23 22:17) [1]Если говорится что нужно инициализировать то значит нужно, если лень это делать это уже другой вопрос. Соблюдение стандартов - это есть правильно, выдумывание велосипедов, в общих случаях никому не нужно.
Желаю успехов
← →
Dima_dvp (2003-10-23 22:51) [2]to Rouse_ © :
Ты (т.е. Вы) меня не совсем поняли. Вернее совсем не поняли.
Я понимаю, что инициализировать надо. Вопрос в следующем: останеться ли APIRecord после выполнения APIFunction в том же состоянии или нет. Естественно если имеется в виду, что эта запись используется как входной параметр.
← →
andre (2003-10-24 00:05) [3]API RuleZZZ
← →
Rouse_ (2003-10-24 00:12) [4]> Dima_dvp (23.10.03 22:51) [2]
Вопрос неоднозначен, применимо для одних функций, ответ да, для других ответ нет.
Желаю успехов
ЗЫ: Можно и на ты...
← →
Dima_dvp (2003-10-24 00:25) [5]Хорошо - конкретный пример:
В этом коде WLV - связаныый список HWND инкапсулированный в объект
var i: Integer;
MII: tagMENUITEMINFO;
//Список в начало
WLV.Rewind;
//Если не пуст
if WLV.Count > 0 then begin
//###########################################################
//Инициализирую часть MII, не зависящуюю от WLV
ZeroMemory(@MII, SizeOf(MII));
with MII do begin
cbSize := SizeOf(MII);
fMask := MIIM_STRING or MIIM_ID or MIIM_DATA;
fType := MFT_STRING;
hbmpItem := HBMMENU_SYSTEM;
end;
repeat
//Получаю текущий HWND
CurHwnd := WLV.GetCurrent;
//Тут получаю длинну заголовка окна
captionLen := GetWindowTextLength(CurHwnd) + 1;
//NeedMem - заголовок пуст или нет
NeedMem := (captionLen > 1);
//Если пуст
if NeedMem then begin
//Выделяю буфер
GetMem(captionBuf, captionLen);
//Копирую в него заголовок
GetWindowText(CurHwnd, captionBuf, captionLen)
end else begin
//В противном случае использую заголовок по умолчанию
captionBuf := DEFAULT_CAPTION;
captionLen := DEFAULT_CAPTION_LENGTH;
end;
//#######################################################
//Доинициализирую MII тем, что зависит от WLV
with MII do begin
wID := i;
dwItemData := CurHwnd;
dwTypeData := captionBuf;
cch := captionLen;
end;
//Вставляю пункт в меню
if not InsertMenuItem(popUpMenu, 0, True, MII) then begin
MessageBox(m_hwnd, "Еггог", "Еггог", MB_OK);
end else
Inc(i);
//Освобождаю память (если выделял)
if NeedMem then
FreeMem(captionBuf, captionLen);
//Иду к следующему HWND в списке
until not WLV.Next;
Так вот ваше мнение, так можно делать или нет.
На практике работает, но всё же..................
← →
Rouse_ (2003-10-24 00:39) [6]Если именно мое мнение, я всеже так бы не делал, но, если использовать Ваш взгляд на эту проблему, можно конечно и так (сильно тщательно в код не всматривался). По идее ошибок быть не должно. Но нельзя привыкать к такому стилю написания кода, я как понял вы просто решили поставить принципиально проблему ребром, просто для изучения?
Желаю успехов
← →
Dima_dvp (2003-10-24 01:11) [7]Нет давайте продолжим дискуссию в примерах:
Для данного кода разложим цыкла так как они исполняются при условии, что цикл исполняется 3 раза:
Вариант 1:
//Инициализирую часть MII, не зависящуюю от WLV
//Доинициализирую MII тем, что зависит от WLV
//Вставляю пункт в меню
//Доинициализирую MII тем, что зависит от WLV
//Вставляю пункт в меню
//Доинициализирую MII тем, что зависит от WLV
//Вставляю пункт в меню
Вариант 2:
//Инициализирую MII полностью
//Вставляю пункт в меню
//Инициализирую MII полностью
//Вставляю пункт в меню
//Инициализирую MII полностью
//Вставляю пункт в меню
Теперь расчёт:
Предположим что запись MII состит вся из полей типа DWORD и таких полей 20.
Второе приближение: пусть 10 полей зависят от WLH и 10 не зависят.
Тогда получается примерно следующее
Вариант 1:
10 + 10*3 = 40 раз копирется DWORD
Вариант 2:
20 * 3 = 60 раз копируется DWORD
Вывод: Потеря производительности (хоть и смешная)
А если отвлечься и представить запись из 100 DWORD. А если из этих 100 зависит только 1.
Ну так как теперь? Будем пренебрегать тем фактом, что ф-ия API может изменить запись? Или так ибудем бесконечно обнулять и инициализировать одним и тем же горы полей???
По моему вопрос вполне резонен. Тем более если программа пишеться маленькая и главным её достоинством должно быть, то что она вообще не мешает.
А мне это для личного счастья хочеться оптимизировать.
← →
Dima_dvp (2003-10-24 01:13) [8]Кстсит если 100 полей DWORD и завист только одно - соотношение будет (99+N) к (100*N) , где N - кол-во итераций цикла
← →
Rouse_ (2003-10-24 09:46) [9]Ну раз продолжим то давайте сделаем так, сделайте два больших цикла к примеру до 1000000000 и прогоните вариант с полной инициализацией а во втором с частичной, замерьте время и скажите его сюда, после будем решать, если расхождение будет незначительное то лучше делать полную инициализацию, в противном случае можно обсудить и Ваш вариант.
Желаю успехов
ЗЫ: для надежности прогоните тест раза три - четыре.
← →
Dima_dvp (2003-10-24 14:41) [10]:) а если я прогоню на Pentium233 разница будет на лицо наверное
Страницы: 1 вся ветка
Форум: "Потрепаться";
Текущий архив: 2003.11.13;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.032 c