【问题标题】:SetWindowText Slow, Win32 C++SetWindowText 慢,Win32 C++
【发布时间】:2013-05-18 18:22:18
【问题描述】:

我有一个简单的应用程序,我在其中读取一些内部变量并将它们发布到菜单上的 EditControl。

这是一个代码sn-p

case 0:
        SetWindowText(GetDlgItem( gHWnd, IDC_PACKETID ), 
                     (LPSTR)std::to_string(long long(NC->mPacketNum)).c_str());
        break;

所以那里发生了很多事情。我只是想将一个数字转换为可以在编辑对话框中显示的东西。这太慢了,我只要进入这个部分就可以从 50Hz 下降到大约 30Hz。

有什么想法可以显着加快速度吗?

【问题讨论】:

  • 使用SetDlgItemInt可以大大简化这行代码。
  • 谢谢。我会试试的。我还尝试了 LPCTSTR(NC->mPacketNum),它工作正常,除非将该变量更改为浮点数。
  • 基于浮点数的东西有什么简化吗?或者它会是一个 SetDlgItemText 的东西,带有浮点到文本的转换。
  • 是的,我认为没有 MS 提供的浮点数包装器。 SetDlgItemText 仍然保存单独的 GetDlgItem
  • 我写了一个快速测试来分析 SetWindowText,它花了 78 微秒。使用适当的分析器来查找问题。

标签: winapi user-interface


【解决方案1】:

我通过维护上次窗口更新的时间戳来解决此类问题。然后,除非经过一定时间,否则我会阻止另一次更新。 1/10 秒对我来说似乎很有效。性能显着提高,更新看起来仍然很流畅。

【讨论】:

  • 谢谢.... 这样做了,但每次通话都非常昂贵,而不是累积。尝试上面的建议,这可能是我正在做的一件事导致悲伤。
【解决方案2】:

在这段代码中发生了很多事情。

SetWindowText 本身似乎不太可能是缓慢的部分。让我们一块一块地拆开,看看时间可能会去哪里。 (确定的唯一方法是分析,但我不能为你做到这一点,所以我正在寻找可能性。这取决于你来衡量。)

SetWindowText(GetDlgItem( gHWnd, IDC_PACKETID ), 
              (LPSTR)std::to_string(long long(NC->mPacketNum)).c_str());
  1. GetDlgItem 调用可能正在发送消息以遍历 gHWnd 的子窗口。如果有很多孩子,并且 IDC_PACKETID 不是第一个,这可能会花费一些时间。考虑计算一次并缓存结果。除非您销毁控件并创建一个新控件,否则 HWND 不会更改。

  2. 您正在使用 ASCII 字符串调用 SetWindowText。 (你为什么要转换结果?而且,特别是,你为什么要放弃 const-ness?)如果你使用的是现代版本的 Windows,那么你的 ASCII 字符串会被即时转换为宽字符串,这可能涉及额外的动态内存管理。您可以调用 SetWindowTextW(注意 W 后缀)并直接使用 std::to_wstring 计算宽字符串。根据 std::to_wstring 的实现细节,这可能会更快。

  3. 窗口真的是一个编辑控件吗?如果您以 30-50 Hz 的频率对其进行更改,您似乎不太可能需要一个成熟的编辑控件。您可以改用静态文本控件吗?它可能有一个更简单和更快的实现。

  4. NC->mPacketNum 是否会在很长一段时间内正确对齐?如果未对齐,则会对性能产生不利影响。看看你能不能保证对齐。

【讨论】:

  • 谢谢,我会尽力的。现在玩探查器。 McAfee Host Intrusion Prevention 不喜欢它,但我正在想办法让它发挥作用。谢谢您的帮助。当我减少时间时,我会回复,以便其他人知道答案是什么。
【解决方案3】:

对于高帧率,您需要使用 Direct2D 或 OpenGL 渲染,而不是内置的 EDIT 窗口类。

如果您不需要高帧速率,只需要高吞吐量,您可以使用InvalidateRect,并且仅在收到 PAINT 消息时更改文本。 Windows 将限制它向您发送WM_PAINT 的速率。或者使用计时器。通过这种方式,您只需将新值存储在内部变量中,当您获得绘制或计时器回调时,将其从间隔变量移动到 EDIT 控件。

【讨论】:

  • 同意,但我正在编辑旧代码只是为了更新一点东西。希望获得便宜的胜利。
  • @Grommit:嗯,那些渲染在 Win32 窗口客户区域内,但如果你只想快速重绘一个窗口,则不必更换整个 GUI。
  • @Grommit:添加了另一个想法。
  • 谢谢。已经在做等效的事情了....每次发生需要更新的更新时,我都会获得帧速率。这似乎是一个非常缓慢的调用。
猜你喜欢
  • 2010-12-15
  • 2010-12-28
  • 2011-05-01
  • 2020-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-14
  • 1970-01-01
相关资源
最近更新 更多