Delphi; производительность передающей константы представляет в виде строки по сравнению с передающими строками var

Быстрый; действительно ли я прав в размышлении, что, передавая строку методу, 'поскольку КОНСТАНТА' включает больше служебное, чем передача строки как 'VAR'? Компилятор заставит Delphi делать копию строки и затем передавать копию, если строковый параметр будет объявлен как КОНСТАНТА, правильно?

Причина вопроса немного утомительна; у нас есть утилита Delphi 5 прежней версии, дни которой действительно сочтены (замена разрабатывается). Это делает большой объем строковой обработки, часто передавая 1-2Kb строки между различными функциями и процедурами. Всюду по коду 'корректное' наблюдение за использованием КОНСТАНТЫ или VAR для передачи параметров (в зависимости от задания в руке) придерживалось к. Мы просто ищем несколько 'быстрых побед', которые могли бы побрить несколько микросекунд от времени выполнения, для преодолевания нас, пока новая версия не готова. Мы думали об изменении диспетчера памяти от Delphi 5 по умолчанию одного к FastMM, и мы также задались вопросом, стоило ли изменить способ, которым строки розданы - потому что код хорошо работает со строками, переданными как константа, мы не видим проблемы, если мы изменили те объявления на var - код в рамках того метода не собирается менять струну.

Но это действительно имело бы какое-либо значение в реальном выражении? (Программа действительно просто делает большой объем обработки на них 1kb+ish строки; несколько сотен строк в минуту в пиковое время). В перезаписи эти строки сохранены в объектах/переменных класса, таким образом, они действительно не копируются/передаются вокруг таким же образом вообще, но в унаследованном коде это - в значительной степени 'старый школьный' Паскаль.

Естественно мы представим полное выполнение программы для наблюдения, какое значение мы имели, но нет никакого смысла в фактической попытке этого, если мы категорически неправы относительно того, как передача строки работает прежде всего!

11
задан robsoft 23 December 2009 в 07:27
поделиться

4 ответа

Нет, не должно быть никакой разницы в производительности между использованием const или var в вашем случае. В обоих случаях в качестве параметра передается указатель на строку. Если параметр const, то компилятор просто запрещает любые его изменения. Обратите внимание, что это не исключает модификации строки, если вы получите хитрость:

procedure TForm1.Button1Click(Sender: TObject);
var
  s: string;
begin
  s := 'foo bar baz';
  UniqueString(s);
  SetConstCaption(s);
  Caption := s;
end;

procedure TForm1.SetConstCaption(const AValue: string);
var
  P: PChar;
begin
  P := PChar(AValue);
  P[3] := '?';
  Caption := AValue;
end;

Это фактически изменит локальную строковую переменную в вызывающем методе, доказав, что передается только указатель на нее.

Но определенно используйте FastMM4, это должно иметь гораздо больший эффект на производительность.

.
12
ответ дан 3 December 2019 в 02:52
поделиться

const для параметров в Delphi по существу означает «Я не собираюсь изменять это, , и меня также не волнует, передается ли это по значению или по ссылке - меня устраивает то, что наиболее эффективно ". Выделенная жирным шрифтом часть важна, потому что ее действительно можно увидеть. Рассмотрим этот код:

type TFoo =
  record
    x: integer;
    //dummy: array[1..10] of integer;
  end;

procedure Foo(var x1: TFoo; const x2: TFoo);
begin
  WriteLn(x1.x);
  WriteLn(x2.x);

  Inc(x1.x);
  WriteLn;

  WriteLn(x1.x);
  WriteLn(x2.x);
end;

var
  x: TFoo;
begin
  Foo(x, x);
  ReadLn;
end.

Хитрость заключается в том, что мы передаем одну и ту же переменную как var и как const , чтобы наша функция могла изменяться с помощью одного аргумента, и посмотреть, если это влияет на других. Если вы попробуете это с помощью кода выше, вы увидите, что увеличение x1.x внутри Foo не меняет x2.x , поэтому x2 было передано по значению. Но попробуйте раскомментировать объявление массива в TFoo , чтобы его размер стал больше, и запустите его снова - и вы увидите, как x2.x теперь псевдонимы x1.x , так что теперь у нас есть передача по ссылке для x2 !

Подводя итог, const всегда является наиболее эффективным способом передачи параметра любого типа, но вы не должны делать никаких предположений о том, есть ли у вас копия значения, которое было передано вызывающей стороной. или ссылка на какое-то (потенциально измененное другим кодом, который вы можете назвать) местоположение.

или ссылка на какое-то (потенциально измененное другим кодом, который вы можете назвать) местоположение.

или ссылка на какое-то (потенциально измененное другим кодом, который вы можете назвать) местоположение.

9
ответ дан 3 December 2019 в 02:52
поделиться

Компилятор не будет делать копию строки при использовании const afaik. Использование const избавляет вас от накладных расходов по инкременту/декремлению счетчика ссылок на используемую строку.

Вы получите больший прирост производительности, обновив memorymanager до FastMM, а так как вы много делаете со строками, то подумайте об использовании библиотеки FastCode.

.
3
ответ дан 3 December 2019 в 02:52
поделиться

Const уже является наиболее эффективным способом передачи параметров в функцию. Он позволяет избежать создания копии (по умолчанию, по значению) или даже передачи указателя (var, по ссылке).
. Это особенно верно для строк, и это действительно был путь, когда вычислительная мощность была ограничена и не могла быть потрачена впустую (отсюда и лейбл "старая школа").

IMO, const должны были быть конвенцией по умолчанию, так как программист должен был изменять ее, когда это действительно требовалось по значению или по var. Это больше соответствовало бы общей безопасности Паскаля (Pascal) (как в ограничении возможности застрелиться в ногу).

My 2¢...

2
ответ дан 3 December 2019 в 02:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: