转帖:DELPHI用const来提高应用程序在多核多线程下的性能,该如何解决

转帖:DELPHI用const来提高应用程序在多核多线程下的性能
原帖地址:http://hi.baidu.com/sqldebug/blog/item/07f436104f53ea5af819b8be.html

我们经常在DELPHI中用const来定义常量,用const来保护函数参数,其实在用const保护函数参数还有另一个更为重要的作用,提高应用程序的执行效率,尤其是在多线程多核下效果更明显。原因是:普通的函数参数如Add(AValue: string),编译器在传入参数的时候先把变量复制一份,然后当成AValue传入Add,函数结束的时候进行销毁,你在参数上加了const,编译器在传入参数的时候不会进行复制,而是直接传地址,并在编译期间检查不能修改AValue值,我们知道DELPHI的内存管理在申请内存的时候是会加锁的,因此如果调用函数频繁,而且没有加const,这样会造成线程排队等候,性能会不如单线程,const只是对string、结构体等非基本类型有提高效率的作用,对Integer等基本类型(栈变量)不起作用。

1、const的类型检查,以下代码可以修改const参数的值

Delphi(Pascal) code
 
procedure TFmMain.EditConstParameter(const ARecordTest: TRecordTest);
var
  pPoint: PRecordTest;
begin
  pPoint := @ARecordTest;
  pPoint.A := 1;
  ShowMessage(IntToStr(ARecordTest.A));
end;

procedure TFmMain.btnEditConstClick(Sender: TObject);
var
  ARecordTest: TRecordTest;
begin
  ARecordTest.A := 0;
  EditConstParameter(ARecordTest);
  Inc(ARecordTest.A);
  ShowMessage(IntToStr(ARecordTest.A));
end;


2、const提高代码性能,使用const提高代码性能,大家可以把以下例子在自己电脑上测试。

Delphi(Pascal) code
 
unit Main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, DateUtils;

const
  WM_Complete = WM_USER + 1001;
type
  TRecordTest = record
    A: Integer;
    B: Integer;
    C: Integer;
    D: Integer;
    E: Integer;
    F: Integer;
    AStr: string;
    BStr: string;
    CStr: string;
    DStr: string;
    EStr: string;
    FStr: string;
    FCommit: array[0..15*1024*4] of Char;
  end;
  PRecordTest = ^TRecordTest;

  TTestThread = class;

  TFmMain = class(TForm)
    grpConst: TGroupBox;
    cbbConstThreadNum: TComboBox;
    lblThreadConst: TLabel;
    btnConstStart: TButton;
    btnConstStop: TButton;
    grp1: TGroupBox;
    lbl1: TLabel;
    cbbUnConstThreadNum: TComboBox;
    btnUnConstStart: TButton;
    btnUnConstStop: TButton;
    mmoText: TMemo;
    btnEditConst: TButton;
    procedure btnConstStartClick(Sender: TObject);
    procedure btnConstStopClick(Sender: TObject);
    procedure btnUnConstStartClick(Sender: TObject);
    procedure btnUnConstStopClick(Sender: TObject);
    procedure btnEditConstClick(Sender: TObject);
  private
    { Private declarations }
    FStartTime, FEndTime: TDateTime;
    FConstThread, FUnConstThread: array of TTestThread;
  protected
    procedure WMComplete(var Msg: TMessage); message WM_Complete;
  public
    {* 修改const函数变量 *}
    procedure EditConstParameter(const ARecordTest: TRecordTest);
    {* 线程测试函数 *}
    function ConstTestA(const ARecordTest: TRecordTest): Integer;
    function ConstTestB(const ARecordTest: TRecordTest): Integer;
    function ConstTestC(const ARecordTest: TRecordTest): Integer;
    function ConstTestD(const ARecordTest: TRecordTest): Integer;
    function ConstTestE(const ARecordTest: TRecordTest): Integer;
    function ConstTestF(const ARecordTest: TRecordTest): Integer;
    function UnConstTestA(ARecordTest: TRecordTest): Integer;