Форум: "Основная";
Текущий архив: 2004.08.29;
Скачать: [xml.tar.bz2];
ВнизКакая разница? Const или нет Найти похожие ветки
← →
Iconka © (2004-08-13 11:33) [0]Какая разница в объявлении процедуры:
procedure MyProc(const MyParam: string);
иprocedure MyProc(MyParam: string);
На что, в данном случае, влияет const?
← →
Ega23 © (2004-08-13 11:34) [1]ИМХО, const можно пропускать. Это по умолчанию. Но можно и писать.
← →
Sandman25 © (2004-08-13 11:38) [2][1] Ega23 © (13.08.04 11:34)
Нет.
В данном случае const очень сильно влияет на производительность (либо передается адрес в регистре, либо ВСЯ СТРОКА записывается в стек).
В общем случае const влияет на попытку присвоить значение параметру :)
← →
Digitman © (2004-08-13 11:48) [3]
> Sandman25 © (13.08.04 11:38) [2]
> либо ВСЯ СТРОКА записывается в стек).
ну чушь же !
> Iconka © (13.08.04 11:33)
1.
procedure MyProc(const MyParam: string);
в процедуру передается адрес упр.структуры оригинальной строки
компилятор пресекает попытки изменений MyParam
2.
procedure MyProc(MyParam: string);
в процедуру передается адрес упр.структуры временной копии оригинальной строки
компилятор не запрещает обращаться к MyParam с целью модификации
все изменения, выполненные телом процедуры в отношении MyParam, никак не влияют на оригинал, с которого была сделана копия
время жизни копии = времени исполнения процедуры , т.е. параметр по сути является лок.переменной процедуры
в случае если в кач-ве параметра передается интерфейс-наследник IUnknown, компилятор так же действует по-разному : если интерфейс передается константой, компилятор не вставляет неявный код вызова _AddRef/_Release, в противном случае компилятор формирует неявный код вызова этих методов
← →
Sandman25 © (2004-08-13 11:50) [4]>ну чушь же !
А если String=ShortString?
← →
Iconka © (2004-08-13 11:52) [5]
> 2.
> procedure MyProc(MyParam: string);
>
> в процедуру передается адрес упр.структуры временной копии
> оригинальной строки
А как же быть сprocedure MyProc(VAR MyParam: string);
Ведь в данном случае тоже передается адрес копии переменной. Какая разница?
← →
Sandman25 © (2004-08-13 11:53) [6][3] Digitman © (13.08.04 11:48)
Посмотрел CPU. Признаю, был неправ.
← →
Рамиль © (2004-08-13 11:54) [7]
> [3] Digitman © (13.08.04 11:48)
А разве копия строки делается не в момент попытки модификации? Или в процедуре по другому?
← →
Sandman25 © (2004-08-13 11:58) [8]Using const allows the compiler to optimize code for structured- and string-type parameters.
Help меня обманул :(
Код в обоих случаях будет одинаковым, никакого прироста производительности.
← →
Digitman © (2004-08-13 11:59) [9]
> Рамиль © (13.08.04 11:54) [7]
да , именно так ... мне это следовало бы явно заметить ... т.е. если попытки модификации нет, то оба вызова эквивалентны с т.з. логики и генерируемого компилятором кода
← →
Леван (2004-08-13 11:59) [10]TO Iconka:
при procedure MyProc(VAR MyParam: string)
в процедуру передается адрес упр.структуры оригинальной строки
компилятор не пресекает попытки изменений MyParam
наоборот, изменения, внес енние процедурой в MyParam,
происходять в оригинальной строке
я так думаю
Леван
← →
Думкин © (2004-08-13 12:02) [11]Покурим такой код:
function ConstString (const s : string) : integer;
begin
Result := length(s)
end;
function NoConstString (s : string) : integer;
begin
Result := length(s)
end;
procedure TForm1.Button2Click(Sender: TObject);
var s : string;
i : integer;
Tick : Cardinal;
begin
Screen.Cursor := crHourGlass;
Tick := GetTickCount;
s := "123";
try
for i := 0 to 10000000 do ConstString(s)
finally
Tick := GetTickCount - Tick;
Button2.Caption := IntToStr(Tick);
Screen.Cursor := crDefault
end
end;
procedure TForm1.Button3Click(Sender: TObject);
var s : string;
i : integer;
Tick : Cardinal;
begin
Screen.Cursor := crHourGlass;
Tick := GetTickCount;
s := "123";
try
for i := 0 to 10000000 do NoConstString(s)
finally
Tick := GetTickCount - Tick;
Button3.Caption := IntToStr(Tick);
Screen.Cursor := crDefault
end
end;
← →
KSergey © (2004-08-13 12:05) [12]Просто замечу, что, если на входе будет не String, а структура, то при var и const передастся ее адрес, а без них - вся через стек.
← →
FastByte (2004-08-13 12:06) [13]const в данном случае означает константный-неизменяемый параметр MyParam.
Внутри процедуры строку нельзя изменять, вернее, не позволено. Очень классная штука, если уметь ей пользоваться :)
Хотя Digitman дал более подробное объяснение :)
← →
Sandman25 © (2004-08-13 12:08) [14][11] Думкин © (13.08.04 12:02)
Ничего не понимаю. Код генерится одинаковый, а время выполнения разное, 94 против 500.
← →
MetalFan © (2004-08-13 12:08) [15]109 / 672
const / без const
← →
Думкин © (2004-08-13 12:10) [16]
> [14] Sandman25 © (13.08.04 12:08)
А скакого он одинаковый? У меня разный.
← →
Sandman25 © (2004-08-13 12:13) [17][11] Думкин © (13.08.04 12:02)
Разобрался вроде. Без const происходит увеличение числа ссылок, это оно тормозит работу.
← →
Digitman © (2004-08-13 12:14) [18]
> >ну чушь же !
>
> А если String=ShortString?
да хоть SuperShortString ! при дифолт-соглашении о вызове параметр передается либо через регистр либо через стек ... но факт.значение параметра предст.собой не строку, а адрес либо ее буфера (стат.строки) либо упр.структуры (дин.строки)
← →
Думкин © (2004-08-13 12:14) [19]> [17] Sandman25 © (13.08.04 12:13)
Так точно. :)
Кстати, книга Бакнелла начинается как раз с этого. :)
← →
Sandman25 © (2004-08-13 12:16) [20][18] Digitman © (13.08.04 12:14)
Понятно. Я почему-то думал, что там compiler magic.
← →
Digitman © (2004-08-13 12:17) [21]
> либо через регистр либо через стек
уточнение - компилятор принимает решение о передаче параметра тем или иным макаром исходя из позиции параметра в списке параметров
← →
REA © (2004-08-13 12:21) [22]Увеличивается число ссылок. Вероятно, при попытке модификации будет сделана копия.
← →
Iconka © (2004-08-13 13:06) [23]Получается что всегда нужно пользоваться const. Или var - если нужно изменять параметр.
← →
Romkin © (2004-08-13 13:19) [24]Да. Если входная строка не менятеся в процедуре - то const.
Для строк. Для integer, например, const не приводит к экономии :))
← →
VMcL © (2004-08-13 13:19) [25]>>Iconka © (13.08.04 13:06) [23]
>Получается что всегда нужно пользоваться const.
Не всегда, но по возможности стОит пользоваться.
← →
Digitman © (2004-08-13 14:04) [26]
> Iconka © (13.08.04 13:06) [23]
> Получается что всегда нужно пользоваться const. Или var
> - если нужно изменять параметр.
необязательно.
если в теле процедуры параметр не предполагается модифицировать, то const или не const - абсолютно индифферентно
а вот если предполагается (и именно - оригинал), то здесь нужен var
← →
Думкин © (2004-08-13 14:06) [27]> [26] Digitman © (13.08.04 14:04)
Упорный ты. Если индиферентно, то как тогда это:
> [11] Думкин © (13.08.04 12:02)
> Покурим такой код:
> [14] Sandman25 © (13.08.04 12:08)
> разное, 94 против 500.
> [15] MetalFan © (13.08.04 12:08)
> 109 / 672
> const / без const
← →
Думкин © (2004-08-13 14:08) [28]Причем можно и так:
procedure ConstString (const s : string);
begin
end;
procedure NoConstString (s : string);
begin
end;
← →
Anatoly Podgoretsky © (2004-08-13 14:08) [29]Romkin © (13.08.04 13:19) [24]
А var к излишним затратам.
← →
Digitman © (2004-08-13 15:01) [30]
> Думкин © (13.08.04 14:06) [27]
> Думкин © (13.08.04 14:08) [28]
да ... не индифферентно ... согласен ...
в случае с
procedure NoConstString (s : string);
begin
end;
у меня в Д5 компилятор (со вкл. опцией оптимизации) вставляет совершенно бестолковый (в прикл.смысле) код, который манипулирует стеком (в первом приближении - понятно почему) и лезет в TLS, кажется, с попыткой предупредить потенц.исключение, которого и в помине нет в этом случае
т.е. получается, что индифферентно с т.з. генерируемого кода вызова, но отнюдь не монопенисуально с т.з. генерируемого кода тела вызываемой процедуры
← →
Sandman25 © (2004-08-13 15:12) [31][30] Digitman © (13.08.04 15:01)
Точно. Я тоже сначала на процедуру не посмотрел, поэтому написал [14]
← →
Digitman © (2004-08-13 15:14) [32]
> Sandman25 © (13.08.04 15:12) [31]
то-то и оно ... и я вот поленился) ... а на самом деле все четко и понятно ... по кр.мере - в Д5.5
← →
Digitman © (2004-08-13 15:17) [33]со строками - одно дело, а вот с интерфейсами, переданными в кач-ве параметров, ситуация посложней ... здесь нужно отчетливо представлять себе механику подсчета ссылок, код которого компилятор генерит по разному в том или ином случае
← →
GuAV © (2004-08-13 15:18) [34]
> Да. Если входная строка не менятеся в процедуре - то const.
> Для строк. Для integer, например, const не приводит к экономии
> :))
Моё имхо.
строка - это 4 байта. При сonst передаётся по значению этих четырёх байт, при var - по ссылке на эти 4 байта. Без const/var -тоже позначению. Const только запрещает её модифицировать.
Integer - это 4 байта. Всё аналогично.
Int64 - это 8 байт. Но при const в стек может толкаться значение, если это - единственный параметр (точнее, в EAX:EDX при register).
Вот для записей и ShortString действительно делается копия.
← →
Sandman25 © (2004-08-13 15:21) [35][32] Digitman © (13.08.04 15:14)
Я в 4 и 6 проверял, точно так же. В 3 не нашел, где CPU смотреть :)
← →
GuAV © (2004-08-13 15:28) [36]GuAV © (13.08.04 15:18) [34]
Извините, бред написал...
← →
Digitman © (2004-08-13 15:32) [37]
> GuAV © (13.08.04 15:28) [36]
от уж точно)
какой там нафих Int64, если адресация в Вин32 - 4-хбайтная ?
> при var - по ссылке на эти 4 байта
читай - те же 4 байта в Вин32
после чего в теле делается
mov РОН, [РОН] (если через регистр)
← →
Digitman © (2004-08-13 15:34) [38]
> Sandman25 © (13.08.04 15:21) [35]
> В 3 не нашел, где CPU смотреть
я уже не помню... там, кажется, какая-то заморочка была с этим окном ... типа необходимо было в реестре "ручками" что-то подправить ...
← →
Sandman25 © (2004-08-13 15:38) [39][38] Digitman © (13.08.04 15:34)
Понятно.
Спасибо, мне кода и вдругих версиях хватает :)
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.08.29;
Скачать: [xml.tar.bz2];
Память: 0.54 MB
Время: 0.036 c