Node.js与C ++在数学方面的比较

27

我需要撰写一个实现一些模糊逻辑的服务器程序,并选择使用Node.js编写以利用其事件导向性。 我需要处理困难的数学计算问题,但不知道获得最佳性能的最好方法:

  1. 全部使用Node.js 并利用V8引擎的功能来完成数学任务。
  2. 在C ++中编写模块 实现所有数学函数并从Node中调用它。

有没有人在这两个平台上进行过此类计算的经验?


4
如果编写正确,用 C++ 编写显然会更快。这取决于可接受的性能水平。也许可以先尝试使用 Node.js 编写,然后进行分析以查看它是否是瓶颈。 - Pete
22
“利用V8引擎的动力”让我笑了。 - ziggystar
1
如果你只是需要做 2+2 的运算,那么使用 Node.js 将会是最好的选择。但是,如果你需要进行大型矩阵操作,推荐使用 C 或者 C++。相信你已经明白我的意思了。 - Saleem
1
可以同时实现 - https://nodejs.org/api/addons.html - Mr. Demetrius Michael
2+2并不意味着Node是最佳选择。 - Head Wizard Locke
https://github.com/nodejs/node-addon-api - Emobe
8个回答

51

既然您已经需要 Node.js 部分,那么请继续在 Node.js 中实现所有内容。如果运行速度足够快且易于维护,则这很容易。很难预测虚拟机/JIT 编译器的性能。

如果速度不够快,请首先考虑算法的改进。如果这不能解决问题,并且分析显示计算是问题所在,请继续使用 C++ 重新实现。但请注意编写高效的 C++ 代码并非易事。确保您手边有一个好的分析工具,并经常进行测量。

总的来说,如果正确编写,C++ 代码会更快。棘手的部分在于如何正确编写它。请参阅此文章Google Paper on C++, Java, Scala, Go了解更多信息。精髓是——托管语言使编写和维护代码更加容易,但如果需要原始性能,则 C++ 是最佳选择。但它需要大量专业知识,而且代码更难维护。


5
完全同意。我大约一周前读了一篇文章,展示了JavaScript在某些数值代码上比Java表现出色。很难预测JIT编译器或解释器在哪些情况下能够良好运行。但是始终从可能起作用的简单方法开始。你几乎肯定可以比C++更快地实现JavaScript。因此,首先从那个开始,必要时再在C++中重新实现。 - jalf
@jalf 我认为,预测jit反优化并不难,但是调试错误却很困难。Javascript现在没有方便的工具来完成这些任务。你可以查看调试跟踪,但这非常无聊。如果你有非常复杂的库或需要64位整数/双精度浮点数 - 直接绑定到C/C++可能更快。但对于简单的情况,我同意先编写js更加优化。 - Vitaly
你肯定可以比JavaScript实现更快地开始使用C++,所以从那里开始,除了用于WebAssembly引导之外,你将永远不必再使用JS。 - Pablo Ariel

25

denshade,你的C实现只支持2e5而不是2e6,就像你为js所做的一样(链接到GitHub上今天的版本):

将输出重定向到/dev/null,并将js也更改为2e5,在我的电脑上使用一些版本的node,C大约需要6.5秒,js大约需要8.5秒。

由于您的算法是O(n^2),我预计2e6需要大约15分钟,而不是15小时,但我还没有尝试过。也许有某些原因导致它表现得很糟糕。

(请注意,我无法直接进行评论,因为我在SO上是全新的,没有声望。)


8
这种问题很难回答。对于这些问题,答案总是取决于你的技能以及你愿意投入多少时间和精力。
C++始终有可能更快更高效,因为你可以更加精确地控制所涉及的所有要素。但不足之处在于你必须完成所有有关的事情,而其他语言中的泛型实现可能是由知道该怎么做的人完成的,并且很可能比C++中的朴素或快速实现要好。
此外,通常你会发现瓶颈并不是你想象中的那样,例如,如果读取数据的时间比计算时间长20倍,这并非不可能,那么计算速度快与否都无关紧要。即使对于有经验的开发人员来说,对瓶颈所在的直觉判断往往也是错误的。

在C++中,你不必做JS已经解决的事情,这是不正确的。标准的C++已经包含了编写这样程序所需的一切,并且它是由非常熟练的专业人员编写的,这些人很难被JS程序员匹敌。 - Pablo Ariel

8

4
考虑使用C++进行复杂数学计算时需要注意,你可以利用现有的高性能库,例如BLAS, LAPACK, ARMA等,其他开发人员已经投入了大量时间和精力提供高度优化的功能。我怀疑你不会在JavaScript中找到类似水平的高性能库。当然,如果你在矩阵计算或线性代数方面存在瓶颈,其中一个C ++库是最好的选择。

3
我已经运行了 @denshade 的代码,并删除了打印和计时,对于 100000 个数字的处理速度非常出色:
  • 3 秒,用于 nodejs!

  • 6 秒,用于 gcc/clang 编译的 c 语言

  • 6 秒,用于 hhvm ( php )

  • 14 秒,用于带有 opcache 的 php7

  • 15 秒,用于不带 opcache 的 php7

Nodejs 如此之快,是因为它经过编译和优化。

所以,也许你只需要自己测试一下哪种语言最适合你的需求。


NodeJS 的问题在于它没有适当的多线程支持,但你总是可以使用 workers/child processes 来解决这个问题,具体取决于你的需求。 - Joseph

1
如果你的计算不是很简单,我想发出一个警告。当你进行重量级计算时,JavaScript非常糟糕。我的故事涉及一个简单的质数程序,你可以在这里找到: https://github.com/denshade/speedFun 长话短说。我创建了一个简单但效率低下的素数检查函数,用C和JavaScript实现。两者的实现方式相同。前2000000个素数在C中验证需要5秒钟。而在JavaScript中,同样的函数在node.js中运行超过16个小时。

10
我刚刚直接运行了你的代码,但没有打印语句,结果是565秒......也许printf()中的I/O缓冲比sys.stdout.write更严格?此外,如果C代码花费了很长时间,可能你的测试主要测试了I/O,这可能不是你想要的。 - Walt W
9
如果所有质数都输出到控制台,那么这个测试是无用的。真正的比较应该只涉及计算 n 个质数。我使用 cout 和 printf() 进行了相同的测试,printf() 的性能要好得多。这个测试有缺陷,因为它的测量结果包括 JavaScript 的 process.stdout.write() 和 C 的 printf() 的性能表现。 - Chad Johnson

0

以下是Node.js作为完美技术伙伴的领域。

● I/O bound ApplicationsData Streaming ApplicationsData Intensive Real-time Applications (DIRT)
● JSON APIs based ApplicationsSingle Page Applications

不建议在CPU密集型应用程序中使用Node.js。

以下是API比较: https://www.linkedin.com/pulse/nodejs-vs-java-which-faster-apis-owen-rubel


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接