接下来我应该学习什么通用语言?

时间:2009-08-14 18:19:20

标签: language-agnostic programming-languages

我目前正在参与编程竞赛(http://contest.github.com),其目标是创建推荐引擎。我开始使用 ruby​​ 进行编码,但很快意识到它对于我想到的算法来说还不够快。所以我切换到 C ,这是我所知道的唯一非脚本语言。当然,速度很快,但每次我必须编写一个for循环时,我都会因为数组的元素(经常是这样)而感到畏缩。

当它出现时:我希望我知道一种快速但高级的语言,轻松编写所有这些密集型计算!

所以我看了我的选择,但这些天有很多选择!这里是我几个月来找到的最好的候选人,有些事情让我感到烦恼(希望你能清理):

  • Clojure :我不确定我是否想进入整个lisp的事情,我喜欢我的语法和残忍。不过我可以说服。
  • Haskell :太学术了?我并不真正关心功能,我只想要一些有效的东西。但它的语法很好,我不介意静态输入。
  • Scala :奇怪的语言。我试了一下,但对我来说感觉很乱/不一致。
  • OCaml :还想知道这是否过于学术化?糟糕的并发支持也困扰着我。
  • Arc :保罗格雷厄姆的口齿不清,太晦涩,再一次,我不确定我是否想学习口齿不清。但我相信这个男人!

有什么建议吗?我非常喜欢函数式语言,因为它们能够轻松地操作列表,但我也对其他选项持开放态度。我想和Java一样快......

我希望能够对列表执行的操作类似于(ruby):

([1, 2, 3, 4] - [2, 3]).map {|i| i * 2 } # which results in [2, 8]

我也更喜欢开源语言。

由于

22 个答案:

答案 0 :(得分:12)

在您列出的语言中,Haskell和Arc都不符合您的“快速”要求 - 两者都比Java慢。您认为Haskell比Java快并且接近C的想法很可能来自一个众所周知的有缺陷的测试,该测试试图通过实现排序来衡量性能。他们错过的一件事是Haskell是懒惰的,因此你需要使用排序的结果来实际执行它;他们只是通过记住当前时间,“调用”排​​序函数和检查时间增量来测量性能。 C版本的测试忠实地执行了排序,Haskell版本只是返回了一个从未调用的懒惰评估版本。

实际上,即使在理论上,Haskell也不能那么快就有很多原因。首先,由于普遍的惰性求值,它通常不能传递原始值,并且必须为表达式生成thunk - 优化器可以减少那些在琐碎的情况下,但不是更复杂的。其次,多态Haskell函数实现为 runtime -polymorphic,而不像C ++模板,其中每个新类型参数都实例化最佳编译的新版本代码。显然,这需要额外的装箱/拆箱。最后,Haskell将很难击败任何体面的VM(例如HotSpot JVM或.NET 2.0+中的CLR),更不用说C / C ++了。

现在已经确定了,让我们继续讨论其他问题。 Scala使用JVM作为后端,因此不会比Java更快 - 如果你使用更高级别的抽象,它很可能会有点慢,但可能在同一个球场。 Clojure也可以在JVM上运行,但它也是动态类型的,并且带来了不可避免的性能损失(我听说它在某种程度上可以通过巧妙的方法来缓解这种情况,但无论如何,其中一些确实是不可避免的。)

离开了OCaml,在你的列表之外,它是唯一一种在有效测试中达到C / C ++编译器性能的唯一语言。应该注意的是,这不是典型的惯用OCaml代码 - 例如,它的多态性也是运行时,类似于Haskell,并且带有适当的惩罚;此外,它的OOP系统是结构性的而不是名义上的,这排除了最佳的基于vtable的实现;因此,它也会比C ++慢(我认为与C ++调度相比,Objective-C调度的执行惩罚接近,但是我没有任何数字来支持它)。如果你偏离某些语言特性,你可以在OCaml中击败C ++,但不幸的是,正是这些特性使得OCaml首先如此具有吸引力。

我的建议是:如果你真的需要速度,请使用C ++。如果您使用STL和Boost等高级库,它可能会相当高级。它没有你可能习惯的一些高级语言抽象,但是库可以弥补这一点 - 有时是完全的,有时是部分的。例如,您不必编写for - 循环来迭代数组 - 您可以使用std::for_eachstd::copy_ifstd::transformstd::accumulate和类似的算法(大多类似于mapfilterfold和类似的传统FP原语),以及Boost.Lambda以减少锅炉。

答案 1 :(得分:6)

为什么不简单的Java或C#?应该比Ruby快,比C更高级别,并拥有庞大的用户群。

答案 2 :(得分:5)

你对几乎所有事情的批评似乎都是“怪异”或“过于学术”。但是,这是什么意思?这是一种模糊的批评,你可以抛出任何不完全主流的不熟悉的语言(即,不是C,C ++,Objective-C,Java,Ruby,Python或PHP)。所有这些语言对于学术界来说都是有益的,对其他任何东西都是坏事。尝试进一步细分您的分析:具体,这些语言让您感到困扰的是什么?你可能会发现你的大脑本能地推开了一些不熟悉的东西。如果是这种情况,那么学习其中一种语言可能是扩展思路的好方法。

或者:听起来你正在寻找一种功能语言,所以你可能会看看F#。它是微软创建的一流CLR语言,因此它不带任何“学术”心理包袱,而且与OCaml非常相似。

答案 3 :(得分:5)

newLISP速度快,体积小,可以轻松地将与C集成,并且内置了相当多的统计函数。

答案 4 :(得分:3)

Haskell是我目前的首选,是一种高性能的高级语言。我也听说过关于OCaml的非常好的事情,但是并没有亲自使用它。

Scala和Clojure将具有与Java相似的性能 - 慢,慢,慢!当然,他们会比Ruby更快,但不是什么?

Arc是MzScheme的一组宏,并不是特别快。如果您需要高性能的LISP,请尝试使用Common LISP - 它可以编译为机器代码。

答案 5 :(得分:3)

Delphi / FreePascal怎么样?他们是原生代码&快速。我做了很多实时图形&与他们一起处理。他们不要求你“低水平”工作,但如果你需要,你可以。此外,如果需要,您可以嵌入汇编程序以获得额外的性能。如果你想要远离Windows,FreePascal是跨平台的。

答案 6 :(得分:2)

D可能符合要求吗?编译为机器代码,但允许使用更高级别的概念进行编程。

答案 7 :(得分:1)

计算? Fortran语言。把裤子从其他任何东西上打掉。

答案 8 :(得分:1)

更新后:

如果你想轻松操作列表,你应该使用Common Lisp。它的平均速度只比C慢2倍(实际上在某些情况下速度更快),它对于列表处理非常有用,它是多范式的(命令式,功能性和OO) - 因此您不必坚持功能性 - 只编程。 SBCL是一个很好的Common Lisp,首先尝试IMO。

不要被像括号这样奇怪的“lispy”事情所困扰。通过语法而不是语义判断语言不仅非常愚蠢,而且括号也是LISP的最大优势之一,因为它们消除了数据和表达式之间的差异,您可以操纵语言本身以使其符合您的需求。

不要听那些建议使用C ++ / C#/ Java的人。 Java功能部分是不存在的。 C ++功能部分很糟糕。 C#代表因为他们的复杂性而让我生病。它们不是真正的多范式命令式/函数式语言,它们是命令式/ OO语言,它们具有一些小的功能位,你不能在其中进行真正的函数式编程。

答案 9 :(得分:1)

C ++或C#和mono。

老实说,要在软件工程领域取得很大成就,你可能不得不围绕这些你觉得令人反感的语言。 Java,C,C ++,C#等可能会出现在涉及编程的职业生涯中。

看起来你做了一些有趣的工作。我鼓励你更加努力地提高你的技术水平。值得努力。

或者,考虑到您的兴趣,Python可能会很好。您可能会发现Smalltalk有趣,甚至ATS

对于某些提示,请查看Language Shootout并按Oscar Boykin进行分析。你已经发现了这个,但是比较Ruby和C我们发现Ruby的速度要慢14到600倍(几个测试的速度要慢100倍)。他还指出Python比Ruby快。 benchmarks for all languages很有意思。

同样有趣的是来自Dan Corlan的基准。

答案 10 :(得分:1)

如果你不介意.NET ......

  1. F# - 基于O'Caml,可以完全访问.NET Framework的多范式语言。正式包含在.NET FW 4.0中
  2. Nemerle - 请参阅F#并添加一个强大的元编程功能。

答案 11 :(得分:1)

对于任何看起来不像您已经使用的语言,您似乎感到不舒服。这会限制你,所以如果你有兴趣扩大你的视野,我会建议你不会感到满意。我不是说你想继续使用任何特定的语言(我有一个明确的偏好,永远不要再触摸Tcl),但你应该尝试一下。

有很好的快速实现Common Lisp,这是一种编写功能程序的简单语言。此外,如果你可以相处,你会发现很多可以用它做的好事。

答案 12 :(得分:1)

Python可以快速运行,尤其是使用NumPy包。以下相关链接:

http://www.scipy.org/PerformancePython

Cython and numpy speed

答案 13 :(得分:0)

如果你想要的东西“与Java一样快”,那么显而易见的解决方案是JRuby

如果安装Netbeans(使用Ruby列下的下载按钮),JRuby是默认解释器。它变得不那么容易了!

答案 14 :(得分:0)

如果你的问题是C笨重的循环,我建议你看看Ada。它允许您使用如下的简单语句遍历整个数组:

for I in array_name'range loop
   --'// Code goes here
end loop;

对于AI项目,我还建议您使用Clips,这是一个可自由使用的推理引擎。

答案 15 :(得分:0)

使用pyrexpsyco的Python可能更适合?可能没有C那么快,但你可以看到常规Python的一些显着加速。

答案 16 :(得分:0)

您可能会考虑使用F# - 它的源代码与OCAML兼容(或者您可以使用更轻量级的语法),而不是OCAML,它支持actor风格的并发性,它支持异步工作流程(实际上它几乎是monad)应用异步执行。)

不是这样 - 正如Scala所示 - 如果你将它构建到一个库中,你需要将演员风格的并发性加入到语言中。其余的只是语法糖。

答案 17 :(得分:0)

考虑Tcl,结合C.在C中做真正的计算密集型的东西,因为这就是你知道怎么做,然后使用Tcl作为粘合剂将高级代码与基于C的代码结合起来。

我提出这个建议并不是因为Tcl必然是这项工作的最佳语言(对于这样的事情,确实没有“最佳”)但是因为你将学到很多关于结合两种不同语言的优点的概念。这是一项重要的技术,无论是Tcl / C,Lua / C,Groovy / Java,Python / C等,都能为您的职业生涯提供良好的服务。

答案 18 :(得分:0)

你可能会考虑python;它支持用C或C ++编写模块,因此您可以使用高级语言编写它,对其进行配置,重新编写算法,如果仍然不够快,可以将热点转换为C或C ++以提高速度。 / p>

答案 19 :(得分:0)

学习C ++并熟悉其标准库。由于你已经“说”C,所以学习起来并不难,但请记住,C ++不仅仅是一个更好的C语言,它是另一种语言,它有自己的概念和方法。

答案 20 :(得分:0)

为什么不Erlang

  • 它与你已经知道的语言不太相似,所以你可以学习新概念
  • 它具有一些有趣的多处理功能
  • 这不是出于学术界的。 Erlang首先是商业语言。
  • 至少有两个重要的开源应用程序:CouchDB和Wings3d

答案 21 :(得分:0)

我相信通过C C ++和Java或.net然后从这里转移到任何一种方式java或.net,因为c更面向机器,C ++和java将为您提供面向对象的学习,然后切换到python(真正欣赏干净的代码而不是C ++和JAVA)。