【发布时间】:2011-04-01 23:25:49
【问题描述】:
erlang 中有一些常见的库函数比它们的 c 等效函数慢得多。
是否可以让 c 代码进行二进制解析和数字运算,并让 erlang 生成进程来运行 c 代码?
【问题讨论】:
-
一个值得编辑的问题:P
-
@Drew 这些天更有条理和简洁。获得天文工程学位肯定会有所帮助。
erlang 中有一些常见的库函数比它们的 c 等效函数慢得多。
是否可以让 c 代码进行二进制解析和数字运算,并让 erlang 生成进程来运行 c 代码?
【问题讨论】:
当然,在优化之后,在极端情况下,C 会更快。如果说更快,则意味着运行得更快。
到目前为止,Erlang 的编写速度更快。根据您对速度的要求,Erlang 可能“足够快”,它可以节省您在 C 语言中搜索错误的时间。
C 代码只会在优化后更快。如果您在 C 和 Erlang 上花费相同的时间,您将获得大致相同的速度(请注意,我在此时间估算中计算了调试和错误修复所花费的时间。这在 Erlang 中会少很多)。
所以:
faster writing = Erlang
faster running (after optimisations) = C
faster running without optimisations = any of the two
任你选。
【讨论】:
基于Erlang FAQ,有两条粗略的经验法则:
主要涉及数字运算和数据处理的代码将比等效的 C 程序慢约 10 倍。这包括几乎所有的“微基准”。
大部分时间都花在与其他系统通信、从故障中恢复和做出复杂决策的大型系统的运行速度至少与等效的 C 程序一样快。
但是对于 Erlang 的数字运算性能不足,官方给出了一些解决方案:
在 C 中实现一个函数并将其目标代码加载到 Erlang 虚拟机中,使其类似于标准 Erlang 函数,但具有本机性能。
通过标准输入和输出文件描述符从 Erlang 虚拟机到外部操作系统进程的面向字节的接口。从 Erlang 的角度来看,与该端口的通信是通过消息传递。
一个动态链接的 C 对象文件,它被加载到 Erlang 虚拟机中并充当端口。从 Erlang 的角度来看,与这个端口驱动程序的通信是通过消息传递。
您可以简单地将您的 Erlang 运行时提升为分布式节点。这样就有了一个规范,可以在 C 中实现 Erlang 运行时,并通过单个接口与 Erlang 节点进行通信。
上述所有解决方案各有利弊,使用时需要格外小心。
【讨论】:
首先在 Erlang 中编写系统的整个逻辑,然后在 C 中实现处理二进制文件。使用 NIF(它是 C 的一种接口)对系统的其余部分非常简单且透明。这是另一个关于与 C Run C Code Block in Erlang 交谈的话题。
在破解 C 之前,请确保您对当前的实现进行了基准测试。它可能会满足您的需求,尤其是最新的 Erlang/OTP 版本 (R14),它引入了对二进制处理的极大增强。
【讨论】:
简单的线程对 erlang 来说并不那么有趣。简单的线程 + 消息传递和 OTP 框架是 erlang 最棒的地方。如果您需要数字运算,请使用 ocaml、python、haskell 之类的东西。 Erlang 非常擅长处理数字。
解析二进制文件是 erlang 最擅长的事情之一,也许是最适合它的事情。 Joe 的书 Programming erlang 很好地涵盖了所有内容,而且使用起来并不昂贵。它还谈到了集成 C 代码并给出了一个例子。源码可以从实用编程那里得到,不需要买书,grep #include什么的就可以了。
【讨论】:
如果您真的追求速度,您应该尝试 C 和 C++ 的 OpenMP 或 MPI 并行编程框架。我建议您查看Patterns for Parallel Programming (link to amazon.com),了解有关 OpenMP 和 MPI 编程模式的详细信息。
erl_nif in Erlang ERTS reference manual 的部分会有所帮助。
【讨论】:
如果你喜欢 Erlang,但想要 C 速度,为什么不选择 JOCAML。它是 OCAML(类似于 Erlang,但在速度方面接近 C)的扩展,专为目前正在进行的多核革命而设计。我喜欢它(我知道超过 10 种编程语言......)
【讨论】:
我使用 C 已经 20 多年了。 最近几年,我几乎只使用 Erlang。 出于明显的原因,C 运行得更快。 然而,如果你做对了,Erlang 对于大多数事情来说已经足够快了。 此外,编写 Erlang 更快更有趣。
对于运行时速度至关重要的算法,它当然可以用C编写,这就是Erlang BIF的方式。
【讨论】:
是的,
但是有不止一种方法,松散地说,其中一些或全部已经列出。
我们应该问:
Erlang 和 C 有何不同)?Erlang?考虑这个帖子可能会有所帮助:Scaling & Speed with Erlang。
【讨论】:
为了解决这个问题,是的,可以让 erlang 调用一些 c 函数来处理特定任务。最常见的方法是使用 NIF - http://erlang.org/doc/tutorial/nif.html。 NIF 仅推荐用于 Erlang 版本 20 左右之前的短时间运行的函数,几毫秒,因为它们是阻塞的,这不能与 Erlang 的抢占式调度程序一起使用。现在使用脏线程它更加灵活,您可以阅读它。
请注意,C 在解析二进制文件方面可能更快,尽管您应该运行测试,但 Erlang 编写代码的速度要快得多。 Erlang 在通过模式匹配解析二进制文件方面做得很好。
【讨论】: