云山雾隐 端隐SDP

企业博客

关于Golang内嵌脚本语言的选择

通常我们在项目上时,有跑脚本的需求,需要内嵌一个脚本语言,方便运维时快速部署和修改代码逻辑。Golang的内嵌语言实现比较多,大致有js和lua两类。考虑到js语言目前比较流行,仅选择js作为脚本语言,以免增加用户学习成本。目前找到3种不同类型的js实现的库:

    * otto:https://github.com/robertkrimen/otto

    * goja:https://github.com/dop251/goja

    * v8go:https://github.com/rogchap/v8go

平台兼容性评估

尝试把这三个库集成到了Golang的mac/Windows 平台下,发现 v8go 无法在目前的交叉编译模式中,交叉编译到Windows 下(cygwin)。

平台兼容性评估结论:

性能/正确性评估

性能评估时,使用递归算法来计算斐波那契数列中的某一项,以便评估该内嵌脚本语言在自身跑逻辑时,对cpu的消耗情况。测试时也使用Golang直接实现的版本来作为性能基准(下表的Golang),同时本测试也评估该内嵌脚本语言实现是否正确。

* 参考 js 代码:

function fib(n) {     if (n < 2) return n;     return fib(n - 2) + fib(n - 1); } console.log(fib(25)); copy

1.第一次测试:计算数列第15项,函数调用次数1973

语言

总时间

相对于Golang的时间倍速

Golang

114.6us

1

v8go

242.0us

13.45

goja

360.4us

75.50

otto

517.8ms

1126.08

2.第二次测试:计算数列第25项,函数调用次数24万(242785)

语言

总时间

相对于Golang的时间倍速

Golang

714.3us

1

v8go

3.912ms

5.48

goja

37.62ms

52.67

otto

512.6ms

717.66

3.第三次测试:计算数列第35项,函数调用次数 2986万(29860703)

语言

总时间

相对于Golang的时间倍速

Golang

44.71ms

1

v8go

110.2ms

2.46

goja

4.4219s

98.91

otto

1.0401min

1395.93

每次计算4种方式均正确,性能测试平台:mac intel i7

性能/正确性评估结论:

按下列优先级进行选择:v8go、goja、otto

结论

1.goja是最终选择,v8go有不少编译上的麻烦(估计能解决,但花费在开发时间上不划算),otto速度太慢,不建议选择;

2.从性能上比较, goja 比 Golang 慢了五十倍以上,却能在5秒内执行2000多万次调用,完全足够应付最开始的运维需求。虽然此处在未来还有较大的优化空间,但为了避免过早优化,现在选择goja即可。