![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Динамические массивы
FXeS © (2005-08-30 14:46:00)Подскажите, что с точки зрения эффективности (т.е. скорость работы и занимаемый объем памяти) лучше - дин. массивы или обычные, но создаваемые "с запасом" ячеек.
Суслик (2005-09-02 20:22:00) [21]
> [34] Кефир87 © (02.09.05 19:55)
А где?
Кефир87 (2005-09-02 19:55:00) [22]Да нет спора. Просто я б не догадался хранить массивы в стэке 8)
begin...end (2005-09-02 17:38:00) [23]К [32]:
> от содержимого указателя отнимается $fffffc00 = -1024
В смысле, к содержимому указателя прибавляется -1024. Или отнимается 1024.
begin...end (2005-09-02 17:34:00) [24]> Суслик © (02.09.05 11:31) [29]
Если в подпрограмме, то в стеке (как и любая другая локальная переменная, не удалённая оптимизатором). Если нет, то не в стеке.
> Кефир87 © (02.09.05 17:06) [30]
> На сколько я помню регистр стэка IP
Нет. IP -- это Instruction Pointer. Он содержит часть полного адреса машинной команды, подлежащей выполнению.
> Ну так и как там что-то можно хранить?
ESP -- это указатель на вершину стека. В коде [29] от содержимого указателя отнимается $fffffc00 = -1024, т.е. в стеке резервируется область размером в 1024 байта. Потом можно инициализировать регистр указателя базы кадра стека EBP, и обращаться к размещённым данным, указывая смещение относительно адреса в EBP. Команды PUSH и POP тоже изменяют содержимое ESP, но только либо на 2, либо на 4 байта.
Суслик (2005-09-02 17:25:00) [25]
> [30] Кефир87 © (02.09.05 17:06)
вроде бы esp меняется каждый раз когда делаешь pop или push.
Опать же если не ошибаюсь esp показывает на голову стека.
В общем о чем спор то?
Кефир87 (2005-09-02 17:06:00) [26]Ну и где сдесь стэк?! На сколько я помню регистр стэка IP (или EIP в
32).
А стэк этож ваще что?! Мы туда кладем на верх и берем то что сверху (команды PUSH и POP соответственно) там еще адреса возврата сохраняются командой CALL. Ну так и как там что-то можно хранить? 8)
Суслик (2005-09-02 11:31:00) [27]
> [28] Кефир87 © (01.09.05 22:06)
Вроде в стеке
{$optimization on}
procedure TForm1.Button6Click(Sender: TObject);
var
s: array [0..1023] of byte;
begin
s[1] := 1;
end;
0045AA18 81C400FCFFFF add esp,$fffffc00
0045AA1E C644240101 mov byte ptr [esp+$01],$01
0045AA23 81C400040000 add esp,$00000400
0045AA29 C3 ret
я асм. ваще не знаю, но вроде это стек :) Или нет? Просветите, кто знает :)
Кефир87 (2005-09-01 22:06:00) [28]
> обычный массив в стеке.
Всегда думал что в DS 8)
Игорь Шевченко (2005-09-01 18:35:00) [29]
> Не путаю Tlist выделяет память блоками, и на какой именно
> странице будет расположен блок неизвестно. А при обращении
> к другой странице памяти на неё необходимо переключится.
Путаешь. Переключаться не надо.
Суслик (2005-08-31 15:25:00) [30]
> Не очень понял, что значит "по месту/не по месту", но, ИМХО,
> вызов процедуры для каждого элемента типа integer - не очень
> жизненная ситуация
Про жизненность можно поспорить все-таки. Т.к. сплошной перебор элементов это не 100 процентов вариантов использования массивов. Зачастую в массивах лежал данные, к которым происходит выборочное обращение из разных мест. В этом случае компилатор оптимизировать обращение не может. Разница все же есть, но в несколько процентов. Проверь. Для того, чтобы имитировать обращение к элементам массивов я ввел две процедуры DoD и DoS.
Sapersky (2005-08-31 15:21:00) [31]Если же убрать использование DoS и DoD, а непосредственно изменять знанчения по месту, то разница будет сильная. Но этот случай в жизни редок, т.к. к массиву обычно обращаешься по индексу, неизвестному в момент компиляции.
Не очень понял, что значит "по месту/не по месту", но, ИМХО, вызов процедуры для каждого элемента типа integer - не очень жизненная ситуация. Скорее так:
for i := 0 to High(s) do s[i]:=10
При этом статический быстрее где-то в 1.3 раза, т.к. компилятор обращается к его элементам через инкрементируемый указатель, т.е. код оптимизируется до примерно такого:
pi:=@s[0];
for i := 0 to High(s) do begin pi^:=10; Inc(pi); end;
В случае динамического массива при обращении к каждому элементу заново высчитывается его смещение (start + index * elementsize).
С многомерными динамическими массивами ситуация ещё хуже, т.к. они хранятся не линейно, а как массив указателей. И для каждой размерности смещение нужно считать отдельно.
Суслик (2005-08-31 15:13:00) [32]Ок.
Только флуда тут не видно, вроде даже по теме.
tesseract (2005-08-31 15:11:00) [33]to Суслик >> давай без флуда не по теме tesseract@mail.ru
Суслик (2005-08-31 14:38:00) [34]
> var и как const
вполне может быть.
ничего удивительного, т.к. зачастую при const не происходит увеличения счетчика ссылок. Не буду уствержатьчто это так для дин массивов. Но для интерфейсов это так. Может и для дин. массивов тоже.
-------
Про строки я ничего не говорил. Т.е. про них разговор продолжать бы не хотел.
А вот "порочный" av при дин. массивах было бы интересно посмотреть.
tesseract (2005-08-31 14:35:00) [35]>>по поводу {$rangechecks off/on} ты не прав. Эта опция действительно отключает/включает проверку границ в том числе и в дин. массивах.
Возможно, я как-то реально не пользовался rangecaheck не отключал.
Мне приятнее вставить on EAccessViolation и получить лог присылаемый заказчиком, выяняя где AV.
Для справки посмотри производительность функций:
PosOFChar:=Pos(SomeChar,MyString);
и
function GetCharPos(aCh:AnsiChar; const S: string):integer;
begin
Result:=0;
for i:=1 to length (S) do
if (S[i] = aCh) then
begin
result:=i;
exit;
end;
end;
насчёт try..finally
попробуй передать в функции параметр как var и как const. КАК ПРАВИЛО const быстрее процентов на 10.
Суслик (2005-08-31 14:14:00) [36]
> [18] tesseract © (31.08.05 14:07)
по поводу {$rangechecks off/on} ты не прав. Эта опция действительно отключает/включает проверку границ в том числе и в дин. массивах.
Проверь, cpu посмотри.
Суслик (2005-08-31 14:10:00) [37]
> [18] tesseract © (31.08.05 14:07)
> А проще при работе с разными "опасными" типами данных вроде
> указателей вставляется проверка
А давай подробней. Например, примером кода, где при нормальном использовании дин. массивов есть av. Ты же вроде про это говоришь? На cpu посмотрим, поразбираемся, тогда и обсудим твое высказываение
> Да но выход за пределы массива проверяются
> и скрытые блоки try..except всё равно остаются. AccessViolation
> видел? так вот это как раз реакция на скрытый try..except.
tesseract (2005-08-31 14:07:00) [38]>> можно про это подрбней, что ты имеешь в виду?
Поподробней "Фундаментальные алгоритмы и структуры данных в Delphi". Там про это подробно написано.
А проще при работе с разными "опасными" типами данных вроде указателей вставляется проверка. И мы получаем AV delphi а не "крындец " Винды. Если бы не было проверок всё работало бы не совсем так :-)
Суслик (2005-08-31 14:00:00) [39]
> и скрытые блоки try..except всё равно остаются. AccessViolation
> видел? так вот это как раз реакция на скрытый try..except.
можно про это подрбней, что ты имеешь в виду?
tesseract (2005-08-31 13:51:00) [40]>>насколько мне известно эта проверка отключается {$rangechecks off}
Да но выход за пределы массива проверяются
и скрытые блоки try..except всё равно остаются. AccessViolation видел? так вот это как раз реакция на скрытый try..except.
>> Страницы памяти, ты случайно с винчестером не путаешь
Не путаю Tlist выделяет память блоками, и на какой именно странице будет расположен блок неизвестно. А при обращении к другой странице памяти на неё необходимо переключится.
>>Нука, нука - еще раз про скорость PChar например для определения длины больщой строки.
Запустика две функции поиска /копирования/добавления строк PChar и string - какой метод быстрее?
конечно определение длины строки быстрее в string - там длина в начале строки хранится нечего вычислять.