Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
3-1091706256
MakNik
2004-08-05 15:44
2004.08.29
ADOConnection


3-1091711961
Zabludshiy
2004-08-05 17:19
2004.08.29
Проблема с записью в BLOB-поле


1-1092202179
FastByte
2004-08-11 09:29
2004.08.29
вставка слов в объект класса TRichEdit


3-1091476876
snake1977
2004-08-03 00:01
2004.08.29
JOIN & ORACLE


3-1091788451
Самовар
2004-08-06 14:34
2004.08.29
Удаление пустых записей в базе





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский