控制台应用程序比 GUI 应用程序运行得更快吗? [关闭]
Posted
技术标签:
【中文标题】控制台应用程序比 GUI 应用程序运行得更快吗? [关闭]【英文标题】:Do console apps run faster than GUI apps? [closed] 【发布时间】:2010-04-13 08:50:50 【问题描述】:我对编程世界比较陌生。我有几个性能问题:
控制台应用程序的运行速度是否比具有图形用户界面的应用程序快?
像 C 和 Pascal 这样的语言是否比像 C++ 和 Delphi 这样的面向对象语言更快?我知道语言速度更多地取决于编译器而不是语言本身,但是过程语言的编译器生成的代码是否比 OO 更快(包括可以生成 C 代码的 C++ 编译器)?
【问题讨论】:
代码速度往往更多地取决于代码的质量而不是编写的语言。使用可以编写好的代码的语言工作,速度将是一个附带好处 - 不要不要仅仅因为它应该很快就使用一种语言;如果你不能用那种语言编写好的代码,那么它仍然会很慢。 您应该将您的问题一分为二,因为(除了“更快”位)它们不相关。 @Dav:有些项目确实需要依赖于语言的性能...... Omair 可能不会编写下一个地震引擎,但为什么假设语言性能对任何人都不重要? @Inverse:我的评论更多地是说“不要使用无法编写好的代码的语言”,而不是“使用可以编写好的代码的任何语言” - 在某些情况下,语言选择可能仍然很重要,但是任何你用糟糕的代码编写的语言都会变慢。 【参考方案1】:控制台应用程序是否比基于 Windows 的应用程序运行得更快
简答:否 长答案:
在基于控制台的应用程序中,没有 GUI 线程需要重新绘制窗口并接受用户输入,因此从这个意义上说,控制台应用程序可能会稍微快一些(因为它占用 CPU 周期的线程更少)。但是,由于现代操作系统同时运行多个进程,无论如何,控制台应用程序仍然会与系统中的其他进程竞争 CPU,所以不会。
像 c 和 pascal 这样的语言是否比像 c++ 和 delphi 这样的面向对象语言更快?
简答:否 长答案:
C 和 C++ 中的等效程序的性能大致相同。尽管编程语言当然可以在性能方面发挥作用,但通常您需要担心的主要事情是算法(您使用应用程序逻辑表达的内容),而不是算法编码的语言。
【讨论】:
实际上,在基于控制台的应用程序中,GUI 线程只是对您隐藏。但是像素仍然需要绘制到屏幕上,并且控制台窗口可以拖动,所以显然输入是通过某种方式处理的。 @MSalters,控制台应用程序也可以在后台运行 I/O 重定向,在这种情况下将没有 GUI 线程。虽然,是的,控制台窗口,如果有的话,需要重新绘制并接受 I/O。 快速而肮脏的评论:Delphi 对象代码比 Delphi 过程代码慢一点,因为“self”指针(必须存储在 CPU 寄存器或堆栈中)并且如果您使用许多函数会变慢覆盖。当您在 Delphi 中查看生成的代码时,您可以看到这一点(CPU 视图,CTRL-ALT-C)。 C++ 也有同样的情况:如果你使用目标代码而不是过程代码(如普通 C),由于对象继承等原因,它会产生更多开销。对于嵌入式软件,有时必须使用 C,因为 C++ 太慢了 c.q。开销太大 André Mussche:是的,支持对象需要一些开销。但是,如果这些对象产生更好的设计,那么整个应用程序可能会更快。例如,虚函数调用比重复测试 if else if 阶梯要快得多。 @Andre,在“等效程序”(例如,可重入程序)中,仍然需要传入一个指向包含与该调用有关的数据的结构的指针......它只会不是自动的。例如,考虑 pthread 库中的调用......你仍然需要传入一个“pthread_t”对象,它只是显式的,所以我认为你的陈述是不准确的。如果你使用共享状态,那么它不再是等价的(除非在 OOP 版本中,你使用了一个静态函数,但是你不会有“this”指针)。【参考方案2】:Michael Aaron Safyan 已经给出了很好的答案。我想贡献一点关于为什么面向对象语言有时会与较慢的代码相关联。
现实世界对我们程序员的要求不断迫使我们在更短的时间内编写更多的代码。对于非常熟练的程序员,汇编语言将赢得所有速度记录,因为程序员准确地编写了机器需要执行的操作,而其他代码很少。实际上,大多数编程不是在汇编程序中完成的,因为它非常乏味且容易出错。编译语言使程序员的工作效率更高,因为它们让编译器处理大部分细节工作。
朝着同一个方向进一步发展,Delphi 使用自动字符串:无论何时使用它们都是“正确的”长度;如果您连接两个字符串,则会生成一个新的字符串,该字符串的长度适合前一个字符串的组合。如果您更改该字符串并使其更长,则会创建一个新字符串并自动丢弃前一个字符串。作为一名 C 程序员,您可以预料到程序会做什么,并为较大的字符串分配足够的空间,因此您不必创建一个新字符串并丢弃旧字符串。因此,字符串的内存管理对程序员来说是一种方便,但代价是牺牲了一些 CPU 时间。
同样,面向对象允许您将相关数据组视为同质块而不是字符串和数字。有时并非所有这些信息都是必需的,并且在低级 C 程序中,您可能不需要对象引起的某些操作和内存使用。这又是一个程序员方便而不是 CPU 速度的问题。
最后,一些接口被认为非常复杂,软件公司试图通过创建概念上更简单处理的面向对象框架来使它们易于使用。您可以创建一个窗口对象,而不是调用打开一个窗口,通常会产生一些开销。在一个奇怪的开发中,软件公司和个人开发人员经常构建更进一步的面向对象框架来隐藏或处理其他框架的复杂性。一些旧项目最终会在原始功能之上使用多层面向对象的框架,并且毫不奇怪,由于他们花费大量时间管理自己,因此在消耗大量内存的同时向客户展示了糟糕的性能。
总而言之,面向对象的代码有时会因其使用方式而导致性能不佳;但特别是在 C++ 的情况下,语言中没有任何东西直接导致“慢”。
【讨论】:
@Carl,感谢您的喝彩...不过,我认为您关于汇编语言的陈述是不正确的;除了汇编语言优化大师之外,编译器生成的汇编代码几乎总是比手工编写的汇编代码快。 @Michael:是的,我想我们基本上同意。这就是我的“给定非常熟练的程序员”的意义所在。【参考方案3】:如前所述,您的代码在控制台应用程序中的运行速度通常与在 GUI 应用程序中一样快。
真正的区别在于开销。在所有条件相同的情况下,GUI 应用程序是较大的 EXE,启动和关闭需要更多时间,并且会消耗更多资源。在应用运行时更新 UI 也是一种很好的形式,这可能会占用 CPU 密集型任务的周期。
但在大多数情况下应该没关系。
【讨论】:
【参考方案4】:由于没有消息映射、窗口事件、GUI 线程等......控制台应用程序可能看起来比基于窗口的应用程序具有更快的性能。但是对于您在控制台应用程序和基于窗口的应用程序之间进行选择,速度不应该是唯一的标准。您可能知道 Window 应用程序是“事件驱动编程”
关于语言速度,我不能说只有 c 编译器才能产生更快的执行代码。事实上,c++ 编译器做了很多代码优化,以最大限度地提高编译代码的速度。此外,OO 模型非常适合轻松编程、维护和扩展功能。
所以根据需求使用适当的语言和技术
【讨论】:
“显然”?请详细说明... 对不起,很明显。编辑了我的答案【参考方案5】:像 c 和 pascal 这样的语言是否比像 c++ 和 delphi 这样的面向对象语言更快?
不,反之亦然:
正如 Dav 在他的评论中所说,代码决定了您的应用程序的速度。这也适用于编译器的另一端,即生成的机器代码。
一般而言,较新的编译器通常会产生更快的机器代码,因为它们利用先进的 CPU 功能并执行早期编译器中没有的现代编译器优化。
例如,使用 Delphi 而不是旧的 Turbo Pascal 编译器编译时,可以创建一个运行速度更快的 Pascal 应用程序。
简而言之:不要仅仅因为它们看起来更轻量级而使用旧的/原始的编译器。在大多数情况下,您不会获得任何性能。
【讨论】:
面向对象的代码比过程代码慢,因为对象继承、函数覆盖等额外(但很小)的开销【参考方案6】:由相同编译器生成的相同代码将以相同的速度运行,无论它是在 GUI 应用程序还是控制台中运行。此外,编译为 C++ 的 C 代码(假设它也是 C++ 兼容的)与编译为 C 的相同代码完全不会有显着差异。
但是,操作系统的某些方面可能会影响性能,除非在操作系统或 I/O 调用上被阻止,否则控制台应用程序将消耗它们的整个时间片; GUI 应用程序通常是事件驱动的,所以等待一个事件处理它,然后等待下一个事件;尽管您可能拥有与控制台应用程序类似的工作线程。此外,GUI 应用程序必然会花时间更新其更复杂的显示。但这些方面都在应用程序设计者和操作系统的控制之下,而不是编译器。
就 OOP 而言,它本质上并不慢,但有一些结构和架构可以实现更快的应用程序开发以及更高的可维护性和稳健性,但可能涉及到性能的权衡。
【讨论】:
【参考方案7】:这仅适用于您的第一个问题:
当控制台应用程序在图形环境(例如 GNOME 桌面或 Windows 上)中以交互方式运行时,它们会在实际上是一个 GUI 应用程序的终端窗口中执行此操作。因此,任何 GUI 成本(例如必须运行消息循环、不必分配 GUI 小部件等)都可以简单地转移到托管环境。全屏运行控制台应用程序(text mode 屏幕)确实会减少 CPU 和视频卡之间的流量,但任何速度提升都可以忽略不计。
但是,控制台 UI 更容易开发,但图形输出的灵活性较低。只需比较在 ncurses 中创建表单所需的工作量与使用 GTK 所需的工作量。
【讨论】:
【参考方案8】:关于你的第二个问题,我想回应 Michael 和 Carl,并补充另一个考虑因素 - 即大自然厌恶真空,这适用于源代码。
由于高级语言允许使用更少的代码完成相同的工作,它们也允许使用相同的代码完成更多的工作,即使不需要。
因此,例如,您有时会在这样的 SO 问题上看到:
time starttime = now;
for (i = 0; i < 1000000; i++)
cout << i;
cout << (now - starttime);
并询问这是否乘以循环开销,隐含地假设因为<<
只有两个字符,所以可以忽略不计。事实上,循环内的<<
比循环多花费数千倍的周期。以我的经验,包括我在内的几乎所有程序员都以多种方式完成了这项工作,他们很庆幸可以用很少的代码完成很多工作,他们做了很多并且只是假设,如果他们这样做了,那就需要了。
因此,语言级别越高,the more important is the skill of performance tuning。
【讨论】:
【参考方案9】:感谢大家在这个问题上帮助我 但我仍然很困惑我对oo语言的印象是它们有性能开销,因为它们的库很臃肿。如果你用C++编写使用Blitz++库,它会运行得更快,如果没有c那么快,但是可用于c++的普通库使c++比c慢,同样适用于pascal和delphi,如果你使用delphi7而不是delphi 2010来编译你的程序,它将运行得更快,因为delphi 2010单元更重(警告:我没有将delphi 7与2010进行比较,也没有将c ++与c进行比较,这只是我的印象通过阅读在线论坛和语言与语言辩论创建)你们可能认为我疯了,但我更喜欢一个程序(即使像文本编辑器一样小)以 完美 运行,即使我的程序是在超级计算机上运行我仍然想优化我的代码可能是我有强迫性人格障碍:)
【讨论】:
使用 Delphi 2010 编译的程序可能比使用 Delphi 7 编译的程序更快。从那时起内存管理器发生了变化,Delphi 2010 产生了更好的优化代码(是否使用了 FastCode 代码?)。关于臃肿的库:大型库可能需要更多时间来加载,但执行速度主要受实现(使用的算法)和可能“功能丰富度”的影响。因此,如果库 A 比 B 快,则 A 的编码更好或包含的功能比 B 少,但这与 OO 与过程无关。 “功能丰富”如何让库变慢?我不明白,请澄清 看看 TList 的实现。在旧时代(Delphi 5 之前),当您清除 TList 时,它只是将其内部计数器设置为零并释放为指针列表分配的内存。随着从 TList 派生的 TObjectList 的到来,每次删除项目时都需要通知。因此,当您现在清除 TList 时,它将为列表中的每个项目调用 Delete,这反过来又调用 Notify。清除 TList 现在是 O(n) 操作,之前是 O(1) 操作。所以为了实现 TObjectList 拥有对象的特性,另一种方法变得更慢了。以上是关于控制台应用程序比 GUI 应用程序运行得更快吗? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章