编程语言的性能多久经常成为一个重要问题?

时间:2009-05-19 03:27:39

标签: performance programming-languages

似乎我经常听到人们批评某些编程语言,因为他们“表现不佳”,或者因为某些其他语言一般“更快”(不一定针对特定应用)。但是,我的经验和教育告诉我,无论何时遇到性能问题,至少可能出现以下情况之一:

  1. 瓶颈不在CPU中,而在其他设备中,例如网络或硬盘驱动器。
  2. 性能不佳是由您的算法引起的,而不是由您使用的语言引起的。
  3. 我的总体印象是,编程语言本身的速度在绝大多数情况下都是无关紧要的,严重的数据处理问题除外。即使在这些情况下,我相信你可以使用混合方法,并且只为CPU密集型部分使用低级语言,这样你就不会失去更抽象语言的好处。

    你同意吗?编程语言的速度在大多数时候都是微不足道的,还是评论家有权指出语言表现问题?

    我希望这个问题不是太主观,但在我看来应该有一个相对客观的答案。

5 个答案:

答案 0 :(得分:3)

在图书馆,操作系统等中,性能可能是一个严重的问题。但是,我认为超过90%的原始性能是无关紧要的。

在许多情况下更重要的是TIMING。任何垃圾收集语言在这方面都会有一些不可预测性,这使得它们不适合嵌入式和实时设计空间。

GC'd和“慢”语言的重叠是相当可观的,因此当真正的问题与时间不一致时,您可能会因为速度原因而看到一种语言打折。

有一些分配/线程/等。允许垃圾收集的方案,同时也保证系统部分的运行时间,例如Realtime Java,但我个人并未亲眼看到它在任何地方使用过。

简短回答:大多数时候语言的速度是无关紧要的(在合理范围内),语言选择是基于熟悉程度和可用的库。

答案 1 :(得分:1)

这不可能如此广泛地回答。这就像问大型发动机是否是汽车浪费。嗯,对某些人来说,是的。对于其他人,根本不是。各种各样的。

有许多因素可以发挥作用。你的目标环境是什么?最终用户部署还是服务器?我们假设我们正在讨论服务器的Web开发和编码。众所周知,RoR(相对)缓慢。相比之下,.NET相当快。但是RoR也具有.NET无法与之竞争的RAD特性。

  • 昨天让您的应用程序正常运行的优先级高于可扩展性吗?
  • 您的商业模式是在您服务页面的毫秒数或您上市的时间内生存还是死亡?
  • 您的TCO和应用程序架构是否支持扩展或扩展?你甚至希望扩大规模吗?

这些只是建筑师在制定平台/语言决策时必须回答的极少数问题。速度重要吗?有时。如果我打算编写一个最终需要每秒扩展到数千个事务的LoB服务,并且它将部署在企业环境中,我可能会使用.NET。如果我对像销售Twitter teeshirts这样的Web 2.0业务有所了解,我需要在昨天利用这个想法,我可以知道,在准备之前,我可能不会抨击有足够的业务来关闭网站。

这实在是过分简化了一个非常复杂的问题,但希望说明一点,就是说“说”是否重要是不可能的。

答案 2 :(得分:1)

令人惊讶的是,系统的性能是编程语言,正在执行的系统,系统正在执行的操作以及它依赖的外部资源(网络,磁盘,慢速打印机等)的组合。

如果您的系统速度慢,而不是猜测,请测试它。

如果计算中有任何“规则”,那就是“测试你的假设”。其他一切都是严格的准则。

答案 3 :(得分:1)

我认为这是一个很好的问题。要回答它需要一个考虑性能的一般框架,所以让我试着提供一个。 (其中一些听起来很明显,但请耐心等待。)

为了简单起见, 让我们只考虑具有特定工作的应用程序的简单情况,然后开始,然后完成,您关心的是挂钟时间。我们假设一个标准的CPU循环速率和一个单处理器。

持续时间由时间片流组成(比如纳秒)。要做这项工作,所需的时间最短,通常大于零。没有最长的时间。如果程序花费的时间超过最小纳秒数,那么严格来说,这些纳秒中的一些是不必要的(即由于不良原因)。

因此,为了优化程序的执行时间,有必要找到它不需要花费的纳秒(即没有充分理由)并删除它们。

这样做的一种方法是,如果可能的话,逐步完成程序,并在每个步骤中跟踪它为什么要执行该步骤。如果原因不好,则有机会删除步骤。

另一种方法是从程序执行中随机选择纳秒,并查询其原因。例如,程序计数器可以告诉您程序正在做什么,但调用堆栈可以告诉您原因。为了有充分理由花费纳秒,调用堆栈上的每个调用指令都有充分的理由。如果调用堆栈上的任何指令没有充分的理由,那么就有机会进行优化。实际上,指令在调用堆栈上的时间量是删除它所节省的时间。

在某些高度异步,消息驱动或解释的软件中,调用堆栈可能无法提供足够的信息。在这种情况下,回答为什么给定纳秒的消耗可能会更困难。它可能需要检查更多的状态信息,而不仅仅是调用堆栈。例如,在解释器中,也可能需要检查被解释的程序的堆栈。但是,通常硬件调用堆栈确实提供了足够的信息,因此检查它是一件有用的事情。

现在,试着回答你的问题。

有“热点”之类的东西。这是一小组地址,通常位于调用堆栈的底部。在该代码中花费的纳秒可能有也可能没有充分的理由。

存在“性能问题”这样的问题。这是一个经常说明为什么要花费纳秒的指令,但这没有充分的理由。这样的指令可能处于热点。它也可以是子程序调用指令。 (它不能同时存在。)它可能是一条发送消息以便稍后处理的指令,这种指令没有充分的理由被用掉。为了优化软件,正在寻找这些指令(而不是功能)。

松散地说,语言要么被编译成机器语言,要么被解释。解释语言通常比编译语言慢1或2个数量级,因为它们不断地重新确定他们需要做什么。但是,粗略地说,如果它出现在热点中,这只是一个性能问题。如果一个程序花费所有时间来调用编译库函数,或者等待I / O完成,那么它的执行速度可能并不重要,因为大多数纳秒都是由于其他原因而花费的。

现在,当然,任何语言或程序原则上都可能是高度非最佳的,但就编译器而言,对于热点代码而言,它们大多非常好,可能会给出或占用30%。如果涉及后台进程,如垃圾收集,则会增加开销,但这取决于程序生成垃圾的速率。

总而言之,语言的速度在热点代码中很重要,但在其他地方并不多。通过删除所有其他性能问题来优化程序,并且如果编译器/解释器实际看到热点代码,那么语言的速度很重要。

答案 4 :(得分:1)

你的问题框架非常广泛,所以我会尝试给出一个更狭隘的答案:

  • 除非有充分的理由不这样做,否则应始终从那些有助于项目团队提高工作效率的语言中选择项目的语言,并生成可以轻松适应未来需求的可靠软件。这种权衡通常倾向于使用自动内存管理的高级语言。

    N.B。 很多有充分理由做出其他选择,例如与当前产品和库的兼容性。

  • 有时候,当程序太慢时,加快速度的最快捷最简单的方法就是用新语言重写程序(或关键部分)。这种情况最常发生在解释实现语言并编译新语言时。

    示例:通过重写邮件标题的词法分析,我从OSBF-Lua垃圾邮件过滤器中获得了4倍的加速。通过从Lua重写为C,我不仅从解释到编译,而且能够消除每个输入字符的数组边界检查。

要回答上述问题,不常语言性能本身是一个问题。

相关问题