首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >与GUI应用程序相比,相同的代码运行速度比Windows服务慢

与GUI应用程序相比,相同的代码运行速度比Windows服务慢
EN

Stack Overflow用户
提问于 2012-12-02 23:45:27
回答 1查看 2.3K关注 0票数 3

我有一些Delphi 2007代码,它运行在两个不同的应用程序中,一个是GUI应用程序,另一个是Windows服务。奇怪的是,虽然GUI应用程序在技术上似乎有更多的“要做”、绘制GUI、计算一些统计数据等等,但Windows服务在运行时始终使用更多的CPU。如果GUI应用程序使用的CPU功率约为3-4%,则该服务的使用范围为6-8%。

当它们一起运行时,这两个应用程序的CPU负载大约是两倍。

除了在Windows窗体应用程序中添加GUI代码之外,这两个应用程序中的基本代码是相同的。

有什么原因造成这种行为吗?Windows服务应用程序是否有某种固有的开销,还是我需要查看代码才能在我的书“意外行为”中找到该代码的来源?

编辑:

在有时间更仔细地查看代码之后,我认为下面关于GUI应用程序花费一些时间等待重新绘制,导致CPU负载下降的建议可能是不正确的。应用程序都是线程化的,这意味着GUI重绘不应该影响CPU负载。

为了确保我首先尝试从应用程序中删除所有GUI组件,只留下了一个空白表单。这并没有增加程序的CPU负载。然后,我遍历并删除了用于更新UI的工作线程中的所有同步调用。这有相同的结果: CPU负载没有变化。

服务中的代码如下所示:

代码语言:javascript
运行
复制
procedure TLsOpcServer.ServiceExecute(Sender: TService);
begin
  // Initialize OPC server as NT Service
  dmEngine.AddToLog( sevInfo, 'Service', 'Name', Sender.Name );
  AddLocalServiceKeysToRegistry( Sender.Name );

  dmEngine.AddToLog( sevInfo, 'Service', 'Execute', 'Started' );
  dmEngine.Start( True );
  //
  while not Terminated do
  begin
    ServiceThread.ProcessRequests( True );
  end;

  dmEngine.Stop;
  dmEngine.AddToLog( sevInfo, 'Service', 'Execute', 'Stopped' );
end;

dmEngine.Start将启动并注册OPC服务器,并初始化套接字。然后启动一个线程.接收到的OPC信号。在FormCreate中,对GUI应用程序的主要形式也进行了相同的调用。

接下来,我将研究GUI应用程序是如何启动的,我没有编写这段代码,所以试图弄清楚它是如何工作的,这是一种冒险:)

EDIT2

这有点有趣。我分别运行了两个应用程序1分钟,运行AQTime来对它们进行基准测试。这是结果中最有趣的部分:

在服务中:

程序名称: TSignalList::HandleChild

执行时间: 20.105963821084

日立: 5961231

在GUI应用程序中:

程序名称: TSignalList::HandleChild

执行时间: 7.62424101324976

命中数: 6383010

编辑3:

我终于回到了一个我可以继续研究这个问题的位置。我发现两种程序在5分钟的运行中都有相同的hitcount,但是在服务中执行时间要长得多。对于HandleValue,hitcount为4300258,服务中的执行时间为21.77s,在GUI应用程序中,hitcount为4254018,执行时间为9.75s。

代码如下所示:

代码语言:javascript
运行
复制
function TSignalList.HandleValue(const Signal: string; var Tag: TTag; const CreateIfNotExist: Boolean):        HandleStatus;
var
  Index: integer;
begin
  result := statusNoSignal;
  Tag := nil;

  if not Assigned( Values ) then
  begin
    Values := TValueStrings.Create;
    Values.CaseSensitive  := defDefaultCase;
    Values.Sorted         := True;
    Values.Duplicates     := dupIgnore;
    Index := -1;  // Garantied no items in list
  end else
  begin
    Index := Values.IndexOf( Signal );
  end;

  if Index = -1 then
  begin
    if CreateIfNotExist then
    begin
      // Value signal does not exist create it
      Tag := TTag.Create;
      if Values.AddObject( Signal, Tag ) > -1 then
      begin
        result := statusAdded;
      end;
    end;
  end else
  begin
    Tag := TTag( Values.Objects[ Index ] );
    result := statusExist;
  end;
end;

这两个应用程序输入"CreateIfNotExist“的次数完全相同。TValueStrings是TStringList的直接后代,没有任何重载。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-12-03 02:01:12

您是否计时了核心功能的执行时间?如果是的话,你是否测量了差异?我认为,如果您这样做了,您将不会发现它们之间的差别很大,除非您在核心功能的代码中添加其他功能,比如更新GUI。

消耗较少的CPU并不意味着它运行得更慢。GUI应用程序可能会更频繁地等待重绘,这也取决于GPU (以及系统的其他部分)。因此,GUI应用程序可能消耗较少的CPU功率,因为CPU正在等待系统的其他部分,然后才能继续执行下一条指令。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13675264

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档