Производительность Inline VS Linear String в объектно-ориентированном паскале - Delphi - PullRequest
0 голосов
/ 24 июня 2011

Из-за близкого завершения одного из моих проектов я захотел организовать некоторое обсуждение (в случае, если Роб не дает очень подробного ответа: D), я больше фокусируюсь на некоторой оптимизации памяти и цикла в некоторых областях обработки голодных строк. В моем случае меня интересуют некоторые тесты производительности, если кто-то сделал что-то подобное, для различий производительности, в частности, для двух случаев:

Случай 1: Я использую строковую обработку в строке, поэтому у меня есть одна дополнительная длинная строка, например,

RichEdit1.SelText := stringfunction1(stringfunction2(stringfunction3(stringfunction4, stringfunction5), stringfunction6, stringfunction7(stringfunction8))))

или

Дело 2:

Я просто разделил все эти функции, чтобы каждая выполнялась в отдельной строке, и поэтому я должен объявить переменную, которая буферизует возврат каждой функции.

P.S. Надеюсь, я не ошибся со скобками в случае 1.

Итак, каковы ваши выводы / мнения / критики по этому вопросу?

Может быть, просто не стоит тратить лишнюю наносекунду?

Ответы [ 3 ]

4 голосов
/ 24 июня 2011

Объявление переменных не будет иметь никакого значения, я верю.

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

На самом деле, каждыйКогда вы вызываете функцию со строковым результатом, компилятору нужно создавать временные переменные, потому что функция, возвращающая строку, фактически реализуется как процедура с дополнительным параметром var.

Например:

function GetTempPath : string;

действительно реализован таким образом

procedure GetTempPath(var S : string);

так, учитывая следующую процедуру:

procedure TForm1.Button1Click(Sender: TObject);
begin
  Memo1.Lines.Text := GetTempPath;
end;

Сначала компиляторвыделить временную строковую переменную.Вызывает GetTempPath с указанной временной переменной в параметре.Как только он возвращается, он берет эту переменную и устанавливает ее в Memo1.Lines.Text.По сути, то, что он действительно делает, это:

procedure TForm1.Button1Click(Sender: TObject);
var S : string;
begin
  GetTempPath(S);
  Memo1.Lines.Text := S;
end;

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

procedure TForm1.Button1Click(Sender: TObject);
var S : string;
begin
  S := GetTempPath;
  Memo1.Lines.Text := S;
end;
3 голосов
/ 24 июня 2011

Код

var
  s1, s2: string;
begin
  s1 := 'This is a very long string...';
  s2 := s1;
end;

делает не копирование строки s1 в s2 (что может быть проблемой производительности в узком цикле), но он просто инструктирует *От 1008 * до указывают на то же место в памяти, что и s1.То есть в общем случае присвоение строк переменным не является очень плохой вещью.

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

В целом, я определенно думаю, что вам следует придерживаться подхода, который является наиболее читабельным (для человекапрограммист).Разница в производительности даже не должна быть обнаружена.

0 голосов
/ 09 июля 2011

Хорошо.

Я постараюсь собрать вещи в два предложения.:)

  • Оптимизация строк в основном является преждевременной оптимизацией из-за того, что она является узким местом производительности в ОЧЕНЬ ОЧЕНЬ ОЧЕНЬ ОЧЕНЬ задних ситуациях или случаях использования.

  • Основным преимуществом использования встроенных строк является использование функций компиляторов, которые позволяют повторно использовать предыдущие переменные return (temp) в последующих вызовах параметрических функций.Тем не менее - если мы намереваемся использовать линейные операции, мы должны добавить процедуру GetTempPath () перед кодом выравнивания основной строки, чтобы убедиться, что мы используем старые временные переменные, все еще доступные в памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...