|
|
51CTO旗下网站
|
|
移动端

1.5.2 是否不擅长CPU密集型业务

《深入浅出Node.js》第1章Node简介,从本章开始,我们将逐步揭示它的诸多细节。本节为大家介绍是否不擅长CPU密集型业务。

作者:朴灵来源:人民邮电出版社|2013-11-13 20:38

1.5.2 是否不擅长CPU密集型业务

换一个角度,在CPU密集的应用场景中,Node是否能胜任呢?实际上,V8的执行效率是十分高的。单以执行效率来做评判,V8的执行效率是毋庸置疑的。

我们将相同的斐波那契数列计算(F0=0,F1=1,Fn=F(n 1)+F(n 2)(n≥2))分别用各种脚本语言写了算法实现,并进行了n = 40的计算,以比较性能。这个测试主要偏重CPU栈操作,表1-1是其中一次运算耗时的排行。在这些脚本语言中(其中C和Go语言是静态语言,用于参考),Node是足够高效的,它优秀的运算能力主要来自V8的深度性能优化。

表1-1 计算斐波那契数列的耗时排行

语言

用户态时间

排名

版本

C with -O2

0m0.202s

#0

i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1

(Based on Apple Inc. build 5658)

 (LLVM build 2336.11.00)

NodeC++模块)

0m1.001s

#1

v0.8.8, gcc -O2

Java

0m1.305s

#2

Java(TM) SE Runtime Environment

 (build 1.6.0_35-b10-428-11M3811)

Java HotSpot(TM) 64-Bit Server VM

 (build 20.10-b01-428, mixed mode)

Go

0m1.667s

#3

Go version go1.0.2

Scala

0m1.808s

#4

Scala code runner version 2.9.2

Copyright 2002-2011, LAMP/EPFL

LuaJIT

0m2.579s

#5

LuaJIT 2.0.0-beta10 -- Copyright (C)

2005-2012 Mike Pall.

Node

0m2.872s

#6

v0.8.8

Ruby 2.0.0-p0

0m27.777s

#7

ruby 2.0.0p0 (2013-02-24 revision 39474)

[x86_64-darwin12.2.0]

pypy

0m30.010s

#8

Python 2.7.2 (341e1e3821ff, Jun 07 2012,

15:42:54) [PyPy 1.9.0 with GCC 4.2.1]

Ruby 1.9.x

0m37.404s

#9

ruby 1.9.3p194 (2012-04-20 revision 35410)

 [x86_64-darwin12.1.0]

Lua

0m40.709s

#10

Lua 5.1.4 Copyright (C) 1994-2008

 Lua.org, PUC-Rio

Jython

0m53.699s

#11

Jython 2.5.2

PHP

1m17.728s

#12

PHP 5.4.6 (cli) (built: Sep 8 2012 23:49:53)

Python

1m17.979s

#13

Python 2.7.2

Perl

2m41.259s

#14

This is perl 5, version 12, subversion 4

 (v5.12.4) built for

darwin-thread-
multi-2level

Ruby 1.8.x

3m35.135s

#15

ruby 1.8.7 (2012-02-08 patchlevel 358)

 [universal-darwin12.0]

这样的测试结果尽管不能完全反映出各个语言的性能优劣,但已经可以表明Node在性能上不俗的表现。从另一个角度来说,这可以表明CPU密集型应用其实并不可怕。CPU密集型应用给Node带来的挑战主要是:由于JavaScript单线程的原因,如果有长时间运行的计算(比如大循环),将会导致CPU时间片不能释放,使得后续I/O无法发起。但是适当调整和分解大型运算任务为多个小任务,使得运算能够适时释放,不阻塞I/O调用的发起,这样既可同时享受到并行异步I/O的好处,又能充分利用CPU。

关于CPU密集型应用,Node的异步I/O已经解决了在单线程上CPU与I/O之间阻塞无法重叠利用的问题,I/O阻塞造成的性能浪费远比CPU的影响小。对于长时间运行的计算,如果它的耗时超过普通阻塞I/O的耗时,那么应用场景就需要重新评估,因为这类计算比阻塞I/O还影响效率,甚至说就是一个纯计算的场景,根本没有I/O。此类应用场景或许应当采用多线程的方式进行计算。Node虽然没有提供多线程用于计算支持,但是还是有以下两个方式来充分利用CPU。

Node可以通过编写C/C++扩展的方式更高效地利用CPU,将一些V8不能做到性能极致的地方通过C/C++来实现。由上面的测试结果可以看到,通过C/C++扩展的方式实现斐波那契数列计算,速度比Java还快。

如果单线程的Node不能满足需求,甚至用了C/C++扩展后还觉得不够,那么通过子进程的方式,将一部分Node进程当做常驻服务进程用于计算,然后利用进程间的消息来传递结果,将计算与I/O分离,这样还能充分利用多CPU。

CPU密集不可怕,如何合理调度是诀窍。

【责任编辑:book TEL:(010)68476606】

回书目   上一节   下一节
点赞 0
分享:
大家都在看
猜你喜欢

订阅专栏+更多

活学活用 Ubuntu Server

活学活用 Ubuntu Server

实战直通车
共35章 | UbuntuServer

226人订阅学习

Java EE速成指南

Java EE速成指南

掌握Java核心
共30章 | 51CTO王波

87人订阅学习

Mysql DBA修炼之路

Mysql DBA修炼之路

MySQL入门到高阶
共24章 | 51CTO叶老师

483人订阅学习

读 书 +更多

程序员教程(第2版)

本书按照人事部、信息产业部全国计算机技术与软件专业技术资格(水平)考试程序员考试大纲编写,是对2004版的修订版,内容包括计算机系统、...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊

51CTO服务号

51CTO播客