.includes() 算法和速度?

.includes() algorithm and speed?

我想知道 .includes() 方法使用什么算法?它是否使用像 rabin karp 这样的模块化哈希?

在不了解其方法和速度的情况下,我有点犹豫是否要使用 .includes()。我发现的文档在讨论时没有详细说明(例如 https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/includes

Rabin-Karp 算法是一种字符串搜索算法,但您链接了数组 includes() 算法,与字符串搜索不同,它不依赖于序列。 ECMA specification 指示 实现的方式描述其行为:它按升序将 SameValueZero 应用于每个元素。鉴于该描述,任何普通算法都将是 O(n) 时间和 O(1) 内存。

String.indexOf, on the other hand, doesn't have such a picky specification, and V8 uses a Boyer-Moore-Horspool string search实施。

鉴于不同的引擎可以以不同的方式实现 .includes,因此可能很难对实现做出笼统的陈述。但是,应该可以通过进行一些基准测试来了解它的速度(因为测试可能是唯一可以确定的方法)。

我使用 node 7.0 尝试测试三个不同的函数:
1. includes(),传入一个顺序数组
2. 一个基本的for循环,传入一个顺序数组
3. has(),从顺序数组

中传入一个预先创建的集合

我得到的结果表明数组本身的长度似乎并不重要(正如所希望的那样),但是所需的数字距离开始有多远。对于查找索引 <20 左右的数字,for 循环似乎稍微快一些(可能快 ~15%?)。对于较大的索引,includes() 会超过 for 循环(索引 500 看起来快 2-3 倍)。然而 .has() 在后面的索引处查找数字要快得多(索引 800 快 25-30 倍),索引的大小似乎对其速度影响不大(但创建集合需要时间)。

诚然,这些测试在某种程度上是有限的,许多因素都可能影响它们。一个有趣的结果是,如果一个集合是从传入的数组(而不是其他数组)创建的,即使该集合没有传递到函数中,它似乎也会提高包含的速度,并降低包含的速度for循环功能略。我假设某种类型的缓存以某种方式使 .includes() 受益?