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

Вниз

Какая разница? 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;
Скачать: CL | DM;

Наверх




Память: 0.56 MB
Время: 0.029 c
4-1090178231
nea
2004-07-18 23:17
2004.08.29
Работа с ком портом


1-1092648096
dimon1979
2004-08-16 13:21
2004.08.29
Гиперссылка


14-1092122418
KADAN
2004-08-10 11:20
2004.08.29
SDK по F1


1-1092665101
Zhilkin
2004-08-16 18:05
2004.08.29
Шаблоны текста


1-1092026133
vasko
2004-08-09 08:35
2004.08.29
Перевод строки в CHAR