使用序数类型的const参数有什么优势吗?

时间:2009-10-21 13:57:12

标签: delphi

我知道将字符串参数标记为const可以产生巨大的性能差异,但是序数类型呢?通过制作const我能获得任何收益吗?

我在处理字符串时总是使用const参数,但从不使用IntegerPointer,类实例等。

当使用const时,我经常需要创建额外的临时变量,这些变量会替换现在写保护的参数,所以我想知道:我是否通过将序号参数标记为const来获得任何东西?< / p>

5 个答案:

答案 0 :(得分:46)

你需要了解原因,避免“货物狂热编程”。将字符串标记为const会产生性能差异,因为您不再需要在字符串上使用互锁增量和减少refcount,这个操作实际上变得更加昂贵,而不是更少,因为时间过去因为更多核心意味着需要做更多工作来保持原子操作同步。这是安全的,因为编译器强制执行“此变量不会被更改”约束。

对于通常为4个字节或更少的序数,没有性能增益。使用 const 作为优化只有在使用大于4个字节的值类型(如数组或记录)或引用计数类型(如字符串和接口)时才有效。

然而,还有另一个重要优势:代码可读性。如果你传递的内容为 const ,并且它对编译器没有任何影响,它仍然会对产生影响,因为你可以阅读代码并看到意图这是不能修改的。如果您之前没有看过代码(其他人写过代码),或者如果您在很长一段时间后回复它并且在最初编写它时不记得您的想法,那么这可能很重要。

答案 1 :(得分:18)

您不能意外地将它们视为var参数,并编译代码。所以它使你的意图清晰。

答案 2 :(得分:8)

声明序数类型const没有区别,因为它们无论如何都被复制(按值调用),因此对变量的任何更改都不会影响原始变量。

procedure Foo (Val : Integer)
begin
Val := 2;
end;
...
SomeVar := 3;
Foo (SomeVar);
Assert (SomeVar = 3);

IMHO声明序数类型const没有任何意义,正如你所说,要求你经常引入局部变量。

答案 3 :(得分:1)

这取决于您的日常工作的复杂程度及其使用方式。如果它被用于许多地方并且要求值保持不变,则将其声明为“const”以使其清除且安全。对于字符串类型,如果声明为“const”,则会出现一个错误(对于Delphi 7,因为我残留在它上面)会导致内存损坏。以下是示例代码

type
  TFoo = class 
  private
     FStr: string;
  public
     procedure DoFoo(const AStr: string);
     begin
        FStr := AStr; //the trouble code 1
        ......
     end;
     procedure DoFoo2;
     begin
        .....
        DoFoo(FStr);  //the trouble code 2
     end;
  end;

答案 4 :(得分:0)

使用带字符串的Const可以大大提高速度:

function test(k: string): string;
begin
  Result := k;
end;

function test2(Const k: string): string;
begin
  Result := k;
end;

function test3(Var k: string): string;
begin
  Result := k;
end;

procedure TForm1.Button1Click(Sender: TObject);
Var a: Integer;
    s,b: string;
    x: Int64;
begin
  s := 'jkdfjklf lkjj3i2ej39ijkl  jkl2eje23 io3je32 e832 eu283 89389e3jio3 j938j 839 d983j9';

  PerfTimerInit;
  for a := 1 to 10000000 do
   b := test(s);
  x := PerfTimerStopMS;
  Memo1.Lines.Add('default: '+x.ToString);

  PerfTimerInit;
  for a := 1 to 10000000 do
   b := test2(s);
  x := PerfTimerStopMS;
  Memo1.Lines.Add('const: '+x.ToString);

  PerfTimerInit;
  for a := 1 to 10000000 do
   b := test3(s);
  x := PerfTimerStopMS;
  Memo1.Lines.Add('var: '+x.ToString);
end;
  

默认值:443 const:320 var:325

     

默认值:444 const:303 var:310

     

默认值:444 const:302 var:305

与整数相同:

  

默认值:142 const:13 var:14

有趣的是,在64位中,字符串似乎几乎没有区别(默认模式只比Const慢一点):

  

默认值:352 const:313 var:314