Are there any advantages in using const parameters with an ordinal type?

前端 未结 5 1943
失恋的感觉
失恋的感觉 2020-12-05 06:54

I know marking string parameters as const can make a huge performance difference, but what about ordinal types? Do I gain anything by making them const

相关标签:
5条回答
  • 2020-12-05 07:07

    You need to understand the reason, to avoid "cargo-cult programming." Marking strings as const makes a performance difference because you no longer need to use an interlocked increment and decrement of the refcount on the string, an operation that actually becomes more expensive, not less, as time goes by because more cores means more work that has to be done to keep atomic operations in sync. This is safe to do since the compiler enforces the "this variable will not be changed" constraint.

    For ordinals, which are usually 4 bytes or less, there's no performance gain to be had. Using const as optimization only works when you're using value types that are larger than 4 bytes, such as arrays or records, or reference-counted types such as strings and interfaces.

    However, there's another important advantage: code readability. If you pass something as const and it makes no difference whatsoever to the compiler, it can still make a difference to you, since you can read the code and see that the intention of it was to have this not be modified. That can be significant if you haven't seen the code before (someone else wrote it) or if you're coming back to it after a long time and don't remember exactly what you were thinking when you originally wrote it.

    0 讨论(0)
  • 2020-12-05 07:09

    There's a huge speed improvement using Const with strings:

    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;
    

    default: 443 const: 320 var: 325

    default: 444 const: 303 var: 310

    default: 444 const: 302 var: 305

    Same with Integers:

    default: 142 const: 13 var: 14

    Interestingly though, in 64-bit there seems to be almost no difference with strings (default mode is only a bit slower than Const):

    default: 352 const: 313 var: 314

    0 讨论(0)
  • It depends on how complex is your routine and how it is used. If it is used many places and required that the value stay the same, declare it as "const" to make it cleared and safe. For string type, there was a bug (for Delphi 7 as I stump on it) that causes memory corruption if declare as "const". Below is sample codes

    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;
    
    0 讨论(0)
  • 2020-12-05 07:24

    You can't accidentally treat them like var parameters and have your code compile. So it makes your intentions clear.

    0 讨论(0)
  • 2020-12-05 07:26

    Declaring ordinal types const makes no difference because they are copied anyway (call-by-value), so any changes to the variable do not affect the original variable.

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

    IMHO declaring ordinal types const makes no sense and as you say requires you to introduce local variables often.

    0 讨论(0)
提交回复
热议问题