来自:http://bbs.csdn.net/topics/330048800

---------------------------------------------------------

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

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

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

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

unit Main;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DateUtils; const
WM_Complete = WM_USER + ;
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[..**] 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;
function UnConstTestB(ARecordTest: TRecordTest): Integer;
function UnConstTestC(ARecordTest: TRecordTest): Integer;
function UnConstTestD(ARecordTest: TRecordTest): Integer;
function UnConstTestE(ARecordTest: TRecordTest): Integer;
function UnConstTestF(ARecordTest: TRecordTest): Integer;
end; TTestThread = class(TThread)
private
FConst: Boolean;
protected
procedure Execute; override;
end; var
FmMain: TFmMain; implementation {$R *.dfm} { TFmMain } procedure TFmMain.EditConstParameter(const ARecordTest: TRecordTest);
var
pPoint: PRecordTest;
begin
pPoint := @ARecordTest;
pPoint.A := ;
ShowMessage(IntToStr(ARecordTest.A));
end; procedure TFmMain.btnEditConstClick(Sender: TObject);
var
ARecordTest: TRecordTest;
begin
ARecordTest.A := ;
EditConstParameter(ARecordTest);
Inc(ARecordTest.A);
ShowMessage(IntToStr(ARecordTest.A));
end; function TFmMain.ConstTestA(const ARecordTest: TRecordTest): Integer;
var
i, j: Integer;
begin
j := ARecordTest.A;
for i := to do
begin
j := j + ;
end;
Result := j;
ConstTestB(ARecordTest);
end; function TFmMain.ConstTestB(const ARecordTest: TRecordTest): Integer;
var
i, j: Integer;
begin
j := ARecordTest.A;
for i := to do
begin
j := j + ;
end;
Result := j;
ConstTestC(ARecordTest);
end; function TFmMain.ConstTestC(const ARecordTest: TRecordTest): Integer;
var
i, j: Integer;
begin
j := ARecordTest.A;
for i := to do
begin
j := j + ;
end;
Result := j;
ConstTestD(ARecordTest);
end; function TFmMain.ConstTestD(const ARecordTest: TRecordTest): Integer;
var
i, j: Integer;
begin
j := ARecordTest.A;
for i := to do
begin
j := j + ;
end;
Result := j;
ConstTestE(ARecordTest);
end; function TFmMain.ConstTestE(const ARecordTest: TRecordTest): Integer;
var
i, j: Integer;
begin
j := ARecordTest.A;
for i := to do
begin
j := j + ;
end;
Result := j;
ConstTestF(ARecordTest);
end; function TFmMain.ConstTestF(const ARecordTest: TRecordTest): Integer;
var
i, j: Integer;
begin
j := ARecordTest.A;
for i := to do
begin
j := j + ;
end;
Result := j;
end; function TFmMain.UnConstTestA(ARecordTest: TRecordTest): Integer;
var
i, j: Integer;
begin
j := ARecordTest.A;
for i := to do
begin
j := j + ;
end;
Result := j;
UnConstTestB(ARecordTest);
end; function TFmMain.UnConstTestB(ARecordTest: TRecordTest): Integer;
var
i, j: Integer;
begin
j := ARecordTest.A;
for i := to do
begin
j := j + ;
end;
Result := j;
UnConstTestC(ARecordTest);
end; function TFmMain.UnConstTestC(ARecordTest: TRecordTest): Integer;
var
i, j: Integer;
begin
j := ARecordTest.A;
for i := to do
begin
j := j + ;
end;
Result := j;
UnConstTestD(ARecordTest);
end; function TFmMain.UnConstTestD(ARecordTest: TRecordTest): Integer;
var
i, j: Integer;
begin
j := ARecordTest.A;
for i := to do
begin
j := j + ;
end;
Result := j;
UnConstTestE(ARecordTest);
end; function TFmMain.UnConstTestE(ARecordTest: TRecordTest): Integer;
var
i, j: Integer;
begin
j := ARecordTest.A;
for i := to do
begin
j := j + ;
end;
Result := j;
UnConstTestF(ARecordTest);
end; function TFmMain.UnConstTestF(ARecordTest: TRecordTest): Integer;
var
i, j: Integer;
begin
j := ARecordTest.A;
for i := to do
begin
j := j + ;
end;
Result := j;
end; procedure TFmMain.WMComplete(var Msg: TMessage);
begin
FEndTime := Now;
mmoText.Lines.Add('Spend Time: ' + IntToStr(MilliSecondsBetween(FStartTime, FEndTime)));
end; { TTestThread } procedure TTestThread.Execute;
var
ARecordTest: TRecordTest;
begin
inherited;
ARecordTest.A := ;
while ARecordTest.A < do
begin
if FConst then
begin
Inc(ARecordTest.A);
FmMain.ConstTestA(ARecordTest);
end
else
begin
Inc(ARecordTest.A);
FmMain.UnConstTestA(ARecordTest);
end;
end;
SendMessage(FmMain.Handle, WM_Complete, , );
end; procedure TFmMain.btnConstStartClick(Sender: TObject);
var
i: Integer;
begin
FStartTime := Now;
SetLength(FConstThread, StrToInt(cbbConstThreadNum.Text));
for i := Low(FConstThread) to High(FConstThread) do
begin
FConstThread[i] := TTestThread.Create(True);
FConstThread[i].FreeOnTerminate := True;
FConstThread[i].FConst := True;
end;
for i := Low(FConstThread) to High(FConstThread) do
begin
FConstThread[i].Resume;
end;
btnConstStart.Enabled := False;
btnConstStop.Enabled := True;
end; procedure TFmMain.btnConstStopClick(Sender: TObject);
var
i: Integer;
begin
if Length(FConstThread) = then Exit;
for i := Low(FConstThread) to High(FConstThread) do
begin
FConstThread[i].Terminate;
end;
SetLength(FConstThread, );
btnConstStart.Enabled := True;
btnConstStop.Enabled := False;
end; procedure TFmMain.btnUnConstStartClick(Sender: TObject);
var
i: Integer;
begin
FStartTime := Now;
SetLength(FUnConstThread, StrToInt(cbbUnConstThreadNum.Text));
for i := Low(FUnConstThread) to High(FUnConstThread) do
begin
FUnConstThread[i] := TTestThread.Create(True);
FUnConstThread[i].FreeOnTerminate := True;
FUnConstThread[i].FConst := False;
end;
for i := Low(FUnConstThread) to High(FUnConstThread) do
begin
FUnConstThread[i].Resume;
end;
btnUnConstStart.Enabled := False;
btnUnConstStop.Enabled := True;
end; procedure TFmMain.btnUnConstStopClick(Sender: TObject);
var
i: Integer;
begin
if Length(FUnConstThread) = then Exit;
for i := Low(FUnConstThread) to High(FUnConstThread) do
begin
FUnConstThread[i].Terminate;
end;
SetLength(FUnConstThread, );
btnUnConstStart.Enabled := True;
btnUnConstStop.Enabled := False;
end; end.

DELPHI用const来提高应用程序在多核多线程下的性能的更多相关文章

  1. Linux的虚拟内存管理-如何分配和释放内存,以提高服务器在高并发情况下的性能,从而降低了系统的负载

    Linux的虚拟内存管理有几个关键概念: Linux 虚拟地址空间如何分布?malloc和free是如何分配和释放内存?如何查看堆内内存的碎片情况?既然堆内内存brk和sbrk不能直接释放,为什么不全 ...

  2. 使用异步 I/O 大大提高应用程序的性能

    使用异步 I/O 大大提高应用程序的性能 学习何时以及如何使用 POSIX AIO API Linux® 中最常用的输入/输出(I/O)模型是同步 I/O.在这个模型中,当请求发出之后,应用程序就会阻 ...

  3. delphi 一个自动控制机的硅控板检测程序,用多线程和API,没有用控件,少做改动就能用 用485开发

    一个自动控制机的硅控板检测程序,用多线程和API,没有用控件,少做改动就能用Unit CommThread; Interface Uses  Windows, Classes, SysUtils, G ...

  4. (转)对《30个提高Web程序执行效率的好经验》的理解

    阅读了博客园发布的IT文章<30个提高Web程序执行效率的好经验>,这30条准则对我们web开发是非常有用的,不过大家可能对其中的一些准则是知其然而不知其所以然. 下面是我对这些准则的理解 ...

  5. 提高WPF程序性能的几条建议

    这篇博客将介绍一些提高WPF程序的建议(水平有限,如果建议有误,请指正.) 1. 加快WPF程序的启动速度: (1).减少需要显示的元素数量,去除不需要或者冗余的XAML元素代码. (2).使用UI虚 ...

  6. Delphi XE5教程3:实例程序

    内容源自Delphi XE5 UPDATE 2官方帮助<Delphi Reference>,本人水平有限,欢迎各位高人修正相关错误! 也欢迎各位加入到Delphi学习资料汉化中来,有兴趣者 ...

  7. 解读30个提高Web程序执行效率的好经验

    其实微博是个好东西,关注一些技术博主之后,你不用再逛好多论坛了,因为一些很好的文章微博会告诉你,最近看到酷勤网推荐的一篇文章<30个提高Web程序执行效率的好经验>,文章写得不错,提到一些 ...

  8. 一个用于每一天JavaScript示例-使用缓存计算(memoization)为了提高应用程序性能

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  9. 【翻译】七个习惯提高Python程序的性能

    原文链接:https://www.tutorialdocs.com/article/7-habits-to-improve-python-programs.html 掌握一些技巧,可尽量提高Pytho ...

随机推荐

  1. DFS(2)——hdu1241Oil Deposits

    一.题目回顾 题目链接:Oil Deposits 题意:给你一块网格,网格被分为面积相等的地块,这些地块中标记'@'的是油田,标记'*'的不是油田.已知一块油田与它上下左右以及对角线的油田同属一片油区 ...

  2. Mybatis学习系列(六)延迟加载

    延迟加载其实就是将数据加载时机推迟,比如推迟嵌套查询的执行时机.在Mybatis中经常用到关联查询,但是并不是任何时候都需要立即返回关联查询结果.比如查询订单信息,并不一定需要及时返回订单对应的产品信 ...

  3. 封装 RabbitMQ.NET

    这篇文章内容会很短,主要是想给大家分享下我最近在做一个简单的rabbitmq客户端类库的封装的经验总结,说是简单其实一点都不简单.为了节省时间我主要按照Library的执行顺序来介绍,在你看来这里仅仅 ...

  4. Flink之状态之状态存储 state backends

    流计算中可能有各种方式来保存状态: 窗口操作 使用 了KV操作的函数 继承了CheckpointedFunction的函数 当开始做checkpointing的时候,状态会被持久化到checkpoin ...

  5. 多个jar包的合并

    1.将所有jar文件复制至某临时目录中,通过jar命令解压得到所有的.class文件 > jar -xvf xx.jar xx.jar必须为具体的jar,不能为*.jar,会报FileNotFo ...

  6. JQuery插件supersized.js实现背景图片淡入浅出

    淡入浅出的网站背景图片切换,其实是引用了JQuery插件supersized,效果很炫吧.其实这个插件功能很强大,可以做很多图片类的效果.这些需要等待我们自己去探索. 下面是这个效果的代码只有一行: ...

  7. BZOJ3529 [Sdoi2014]数表 【莫比乌斯反演】

    3529: [Sdoi2014]数表 Time Limit: 10 Sec Memory Limit: 512 MB Submit: 2151 Solved: 1080 [Submit][Status ...

  8. linux管理(二)---网络使用情况的监控

    我们经常在监控服务器或者排查程序性能瓶颈时需要知道  网络带宽的使用情况,看看带宽是不是瓶颈. linux系统中监控网络的工具和命令很多. 但其实主要分2种,一种是实时监控带宽情况(速度如何),一种是 ...

  9. bzoj进度条

    好久没发进度了 这个月没有上个月那么猛,肯能使因为这个月不想水题吧 No. 510 Solved Problems List Solved 368 10001001100210071008101210 ...

  10. Codeforces ----- Kefa and Dishes [状压dp]

    题目传送门:580D 题目大意:给你n道菜以及每道菜一个权值,k个条件,即第y道菜在第x道后马上吃有z的附加值,求从中取m道菜的最大权值 看到这道题,我们会想到去枚举,但是很显然这是会超时的,再一看数 ...