最适合计算和内存昂贵算法的语言

时间:2011-04-11 15:12:41

标签: algorithm data-structures programming-languages np

假设您必须实现一个有效解决NP难问题的工具,不可避免的内存使用量爆炸(输出大小在某些情况下指数输入大小)并且您特别关注这个问题的性能工具在运行时间。一旦知道了基础理论,源代码也必须易读和易懂,而且这个要求与工具本身的效率一样重要。

我个人认为3种语言可能适合这三个要求:c ++,scala,java。 它们都提供了对数据类型的正确抽象,使得可以比较不同的结构或将相同的算法(这也很重要)应用于不同的数据类型。

C ++具有静态编译和优化的优势,并且通过函数内联(如果数据结构和算法经过精心设计)和其他优化技术,可以实现接近纯C的性能,同时保持相当好的性能可读性。 如果您在数据表示中也非常谨慎,那么可以优化缓存性能,当缓存未命中率较低时,缓存性能可以达到数量级。

Java是JIT编译的,它允许在运行时应用优化,并且在这类算法中可能在不同的运行之间具有不同的行为,这可能是一个加号。我担心这样的方法可能会受到垃圾收集器的影响,但是在这种算法的情况下,通常连续分配内存并且Java堆性能比C / C ++好得多,如果你在语言中实现自己的内存管理器,你可以甚至达到很好的效率。 相反,这种方法无法内联方法调用(这会导致巨大的性能损失)并且无法控制缓存性能。在专业人士中,语法比C ++更好,更清晰。

我对scala的担忧与Java大致相同,而且我无法控制语言的优化程度,除非我对编译器和标准库有深入的了解。但是很好:我的语法非常简洁:)

你对这个问题有什么看法?你有没有必须处理这个?您是否会使用这些语言中的任何一种语言实现具有此类属性和要求的算法,或者您会建议其他什么?你会如何比较它们?

4 个答案:

答案 0 :(得分:5)

通常我会在心跳中说“C ++”。秘密在于C ++只会产生需要管理的较少(内存)垃圾。

另一方面,你的观察

  

但是在这种算法的情况下,连续分配内存

是很常见的

暗示Java / Scala实际上可能更适合。但是你也可以在C ++中使用一个小的对象堆。如果内存服务,Boost有一个使用标准allocator接口的接口。

C ++的另一个优点显然是通过模板使用抽象而不会受到惩罚 - 即,您可以轻松创建可以交互的通用算法组件,而不会因抽象而导致运行时开销。事实上,你注意到了

  

可以在保持相当好的可读性的同时实现接近纯C的性能

- 这是以错误的方式看事:Templates allow C++ to achieve performance superior to that of C while still maintaining high abstraction.

答案 1 :(得分:2)

D可能值得一看,看看它如何尝试成为更好的C ++。

答案 2 :(得分:1)

您注意到的语言也是我的第一个猜测。

每种语言对如何处理编译,内存管理和源代码等特定问题有不同的看法,但从理论上讲,它们中的任何一个都应该适合您的问题。

不可能分辨出哪个是最好的,如果你对他们所有人的熟悉程度足以解决他们各自的怪癖,那么可能没有什么重大差别。

显然,如果你真的发现需要优化(我不确定这是否是给定的),那么每种语言都有可能。较低级别的语言显然提供了更多选项,但实际上也更加复杂。

关于C ++与Java的单一说明:这真的是一场神圣的战争,如果你跟随最近的发展,你可能会有自己的看法。我认为Java通常会提供足够好的方面来弥补其缺陷。

关于C ++与C的最后一点说明:据我所知,差异通常相当于一个足够低的百分比来忽略这一点。它对源代码没有任何影响,如果C ++能够使用更容易阅读的源代码,那么可以使用C ++。无论如何,这种选择可以忽略不计。

最后,请记住花费在几个小时的编程/优化上的钱也可以用于稍微优越的硬件以弥补错过的微小细节。

这一切归结为:只要您做得正确(领域知识),您的任何选择都可以。

答案 3 :(得分:1)

我会使用一种语言,可以很容易地处理算法。获得正确的算法,它可以很容易地超过微调错误算法的任何优势。不要害怕用一种通常认为执行速度慢的语言来玩,如果该语言能够更容易表达算法思想。将正确的算法转换成另一种语言通常要容易得多,而不是用最快的执行语言从错误的算法中找出最后的速度渣滓。

所以用你熟悉的语言来表达,这是一种富有表现力的语言。你可能会惊讶自己,发现生产的东西足够快!