奇怪的Node.js性能

奇怪的Node.js性能,node.js,performance,Node.js,Performance,我编写了一个解析字符串的程序(测试长度为5MB)。在一些更改之后,我注意到性能大幅下降,大约30%-35%,因此我开始使用各种性能度量对其进行调试,并发现一些奇怪的地方 结果是,在我删除了算法开头的以下行(只调用了一次)后,我的算法速度急剧减慢: text.match(/\n/g); 如果我简单地把这一行放在算法的顶部,而不使用它的结果,那么性能将提高30-35%,而算法中的其余更改似乎没有任何区别 似乎在内部执行这样的行会在进一步的字符串处理中给Node.js一个提升,我无法进一步解释或分析

我编写了一个解析字符串的程序(测试长度为5MB)。在一些更改之后,我注意到性能大幅下降,大约30%-35%,因此我开始使用各种性能度量对其进行调试,并发现一些奇怪的地方

结果是,在我删除了算法开头的以下行(只调用了一次)后,我的算法速度急剧减慢:

text.match(/\n/g);
如果我简单地把这一行放在算法的顶部,而不使用它的结果,那么性能将提高30-35%,而算法中的其余更改似乎没有任何区别

似乎在内部执行这样的行会在进一步的字符串处理中给Node.js一个提升,我无法进一步解释或分析

然后,我开始在Node.js的不同版本中测试它,并发现这在当前的10.15.3中发生,但在v4.x或v12.x中非常流行

如此巨大的不一致性,以及对性能的完全神秘的影响,我不知道该如何理解

有人能解释一下为什么运行这样一个额外的正则表达式搜索会突然在Node.js中提供一个提升吗?或者在我的情况下是不是有点特殊

更新


我已经记录了一个。

根据V8中字符串的创建方式,它被存储为顺序数组或“切片”(二叉树)。二叉树对缓存的友好程度要低得多,并且由于缓存未命中导致的管道暂停,多次遍历一棵树将导致严重的性能损失

V8中ReGex
match()
的一个副作用是调用
String::flant
。这将导致字符串在内存中顺序化。不幸的是,这种副作用在后来的V8版本中被消除了

节点10公开了一个新函数
%flattString
,该函数可用于显式地对字符串进行排序


作为独立于版本的解决方案,您可以使用该模块。根据V8版本的不同,它会调用
%flattString
Number
(取决于副作用)。

值得指出的是,我曾尝试使用
flattstr
模块,其效果为零,而只需执行
text.match(/\n/g)确实大大提高了性能。