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

Dan*_*ski 33 delphi

我知道标记字符串参数const可以产生巨大的性能差异,但序数类型呢?通过制作它我能获得什么const吗?

我一直使用const处理字符串参数时,却从不为Integer,Pointer,类实例等.

使用时const我经常需要创建额外的临时变量,这些变量会替换现在写保护的参数,所以我想知道:我是否从标记序数参数中获得了什么const

Mas*_*ler 46

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

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

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

  • 关于字符串,你的第一段是错误的.字符串总是作为四字节指针表示传递.`Const`抑制函数的序言和结尾中的代码,用于更新字符串的引用计数.接口参数和动态数组也是如此.同样,记录作为指针传递.`Const`只是抑制了将记录复制到函数本地堆栈的序言代码.换句话说,`const`在函数的*caller*一侧*没有效果*.它只影响呼叫的接收者. (15认同)
  • 如果你认为我说的那样,那么你就不会误读任何东西,Wouter.大于指针*的记录*始终作为指针传递.调用者将指针放在堆栈上.如果参数不是const,则调用的*receiver*生成记录的副本.它与字符串相同.调用者传递指针,接收者复制.在字符串的情况下,制作副本只是更新引用计数. (4认同)
  • @Rob:无法编辑评论.很容易误读你的评论,好像你说记录总是作为指针传递. (2认同)

Cra*_*ntz 18

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

  • 好点,但是不足以指定参数var以使一个人的意图清楚吗? (3认同)
  • Smasher,编译器不区分var和默认约定,只要你允许对方法中的参数做什么. (2认同)

jpf*_*ius 8

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

procedure Foo (Val : Integer)
begin
Val := 2;
end;
...
SomeVar := 3;
Foo (SomeVar);
Assert (SomeVar = 3);
Run Code Online (Sandbox Code Playgroud)

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

  • 克雷格有一个有效的观点.将序数声明为const是有充分理由的; 只是出于性能原因. (2认同)