Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.11.13;
Скачать: CL | DM;

Вниз

К вопросу об оптимизации при работе с 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;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.024 c
3-40877
BKGG
2003-10-21 09:27
2003.11.13
Можно ли как ни будь распознать какой базе принадлежить файл


14-42064
zzet
2003-10-21 14:20
2003.11.13
Задача про 12 монет. Возвращение.


4-42312
wwolf
2003-09-05 09:17
2003.11.13
Блокировка спящего режима


14-41978
Карлсон
2003-10-17 22:27
2003.11.13
вот есть гомофобы, а как называются ненавидящие курящих?


3-41049
inspirion
2003-10-24 12:57
2003.11.13
Помогите советом!