在Delphi中声明本地或全局? [英] Declare Locally or Globally in Delphi?

查看:162
本文介绍了在Delphi中声明本地或全局?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个程序,我的程序调用了数万次,使用这样的通用结构:

  procedure PrintIndiEntry JumpID:string); 

类型
TPeopleIncluded =记录
IndiPtr:指针;
关系:string;
end;

var
PeopleIncluded:TList< TPeopleIncluded>;
PI:TPeopleIncluded;

begin {PrintIndiEntry}

PeopleIncluded:= TList< TPeopleIncluded> .Create;

{在这里确定一个小数字(最多100人)处理的循环}
,while ... do begin

PI.IndiPtr:=。 ..;
PI.Relationship:= ...;
PeopleIncluded.Add(PI);

end;

DoSomeProcess(PeopleIncluded);

PeopleIncluded.Clear;
PeopleIncluded.Free;

end {PrintIndiEntry}

另外,我可以在全局声明PeopleIncluded而不是在本地如下:

 单位过程; 

接口

类型
TPeopleIncluded =记录
IndiPtr:指针;
关系:string;
end;

var
PeopleIncluded:TList< TPeopleIncluded>;
PI:TPeopleIncluded;

程序PrintIndiEntry(JumpID:string);

begin {PrintIndiEntry}

{在这里确定一个小数字(最多100人)处理的循环}
while ... do begin

PI.IndiPtr:= ...;
PI.Relationship:= ...;
PeopleIncluded.Add(PI);

end;

DoSomeProcess(PeopleIncluded);

PeopleIncluded.Clear;

end {PrintIndiEntry}

过程InitializeProcessing;
begin
PeopleIncluded:= TList< TPeopleIncluded> .Create;
end;

过程FinalizeProcessing;
begin
PeopleIncluded.Free;
end;

我的问题是,在这种情况下最好是在全局而不是本地声明PeopleIncluded。我知道这个理论是尽可能在本地定义的,但是我想知道在做数以万计的创造和自由方面是否有任何问题需要担心?让他们成为全球性的只会创造一个创造,一个自由。



在这种情况下推荐的方法是什么?



如果推荐的方法仍然定义它在本地,那么我想知道是否有任何情况下,在本地定义仍然是一个选项时最好定义全局。

解决方案

关于这个过程的可见性,我会做的是创建一个保存所有数据的 c class ,一个用于initalization和一个析构函数的方法,然后调用该过程的一种方法。然后使用探查器优化它的速度。 永远不要使用全局变量,而是将您的进程封装在小型可重用和多线程就绪类中。 速度,简而言之:不成熟的优化是万恶之源 - Donald Knuth引用CAR Hoare的话说。我确信 TList Create / Free 中的瓶颈不是,而是在您的主进程循环中。



因此,在猜测可能会发生什么变化之前,请使用一个分析器来查看瓶颈的位置。查看用于Delphi的分析器和内存分析工具



您可以预先分配变量和/或缓存可重用数据,使用静态数组而不是 TList (或者分配它并通过使用外部 count 变量),并避免分配字符串实例(并传递它们而不用 const 参数)。但是,也许不是一个神奇的解决方案。



为了加快处理速度,改变算法几乎总是比像你这样的低级实施技巧更好试过。使用预先计算的查找表,预先分配内存,避免创建临时字符串(例如,使用 PosEx 副本子链;或者混合 AnsiString / UnicodeString ),避免磁盘,API或数据库调用,更改内存结构,对数据进行排序,然后使用二分搜索,使用散列或非流水线循环,让您处理多线程等等......不可能猜到应该改变什么没有你的进程的全部源代码,并运行真实数据的分析器!


I have a procedure my program calls tens of thousands of times that uses a generic structure like this:

procedure PrintIndiEntry(JumpID: string);

type
  TPeopleIncluded = record
    IndiPtr: pointer;
    Relationship: string;
  end;

var
  PeopleIncluded: TList<TPeopleIncluded>;
  PI: TPeopleIncluded;

begin { PrintIndiEntry }

  PeopleIncluded := TList<TPeopleIncluded>.Create;

 { A loop here that determines a small number (up to 100) people to process }
  while ... do begin

    PI.IndiPtr := ...;
    PI.Relationship := ...;
    PeopleIncluded.Add(PI);

  end;

  DoSomeProcess(PeopleIncluded);

  PeopleIncluded.Clear;
  PeopleIncluded.Free;

end { PrintIndiEntry }

Alternatively, I can declare PeopleIncluded globally rather than locally as follows:

unit process;

interface

type
  TPeopleIncluded = record
    IndiPtr: pointer;
    Relationship: string;
  end;

var
  PeopleIncluded: TList<TPeopleIncluded>;
  PI: TPeopleIncluded;

procedure PrintIndiEntry(JumpID: string);

begin { PrintIndiEntry }

 { A loop here that determines a small number (up to 100) people to process }
  while ... do begin

    PI.IndiPtr := ...;
    PI.Relationship := ...;
    PeopleIncluded.Add(PI);

  end;

  DoSomeProcess(PeopleIncluded);

  PeopleIncluded.Clear;

end { PrintIndiEntry }

procedure InitializeProcessing;
begin
  PeopleIncluded := TList<TPeopleIncluded>.Create;
end;

procedure FinalizeProcessing;
begin
  PeopleIncluded.Free;
end;

My question is whether in this situation it is better to declare PeopleIncluded globally rather than locally. I know the theory is to define locally whenever possible, but I would like to know if there are any issues to worry about with regards to doing tens of thousands of of "create"s and "free"s? Making them global will do only one create and one free.

What is the recommended method to use in this case?

If the recommended method is to still define it locally, then I'm wondering if there are any situations where it is better to define globally when defining locally is still an option.

解决方案

About visibility of the process, what I would make is to create a class holding all the data, one method for initalization and one destructor, then one method to call the process. Then optimize it for speed using a profiler. Never use globals, but encapsulate your process within small reusable and multi-thread-ready classes.

About process speed, in short: "Premature optimization is the root of all evil" — Donald Knuth, quoting C. A. R. Hoare. I'm sure that the bottleneck is not in the TList Create/Free, but within your main process loop.

So use a profiler to see where the bottleneck is, before guessing what may be changed. See Profiler and Memory Analysis Tools for Delphi

You can pre-allocate variables and/or cache reusable data, use static arrays instead of a TList (or allocate it and reuse it by using an external count variable), and avoid allocating string instances (and passing them without a const parameter). But perhaps not a magic solution.

To make process faster, changing the algorithm is almost always better than some low-level implementation tricks like you tried. Use of pre-calculated look-up tables, memory pre-allocation, avoid creating temporary string (e.g. use PosEx instead of copy of sub chains; or mix AnsiString/UnicodeString), avoid disk, API or DB calls, change memory structures, sort data then use binary search, use hashing or un-pipeline loops, make you process multi-thread and so on... it is impossible to guess what should be changed without having the whole source code of your process, and run a profiler on real data!

这篇关于在Delphi中声明本地或全局?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆