Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 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
7-42140
MIA
2003-09-05 01:00
2003.11.13
LPT


1-41187
Pattern
2003-11-02 15:04
2003.11.13
О констукорах и деструкторах компанент


3-40976
kostik78ua
2003-10-16 18:12
2003.11.13
rownum


1-41524
tria
2003-10-28 10:20
2003.11.13
Можно ли поменять цвет TPopupMenu?


3-41045
Maniacosaur
2003-10-24 09:31
2003.11.13
Delphi и MS SQL





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский