JavaScript字符串的比较与数字比较一样快吗? [英] Is JavaScript string comparison just as fast as number comparison?

查看:436
本文介绍了JavaScript字符串的比较与数字比较一样快吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为JavaScript枚举写一个小图书馆。对于我这样做,我需要决定如何存储枚举值。因此,我想在比较时使用最快的方式,但是我也想要一些可调试的东西,所以我在使用字符串或数字之间撕裂了。我知道我也可以使用对象,但这将是另一个问题。



例如

 code> //我不想要这个,因为调试时你会看到值0 
var Planets = {Earth:0,Mars:1,Venus:2}

//我喜欢这个,所以Planets.Earth给我一个很好的可读值(Earth)
var Planets = {Earth:'Earth',Mars:'Mars'}
但是我恐怕当我使用比较它们,如果(myPlanet === Planet。地球),字符串比较可能需要更长的时间(说如果它处于紧密循环中)。应该是这样的,因为 http://ecma-international.org/ecma-262/5.1 /#sec-11.9.6


如果Type(x)为String,则如果x和y为完全相同的字符序列(相同位置的长度和相同字符);否则返回false。


但是当我写了一个测试用例时,我发现他们花费相同的时间http://jsperf.com/string-comparison-versus-number-comparison/2 ,所以它不看起来它正在扫描整个字符串。



我知道这可能是一个微型优化,但我的问题是:使用指针进行字符串等式比较,因此与数字等号比较?

解决方案

字符串比较可以一样快(取决于实现和值) - 或者可能是慢得多。



ECMAScript规范描述了语义,而不是实现。 Know for Certain的唯一方法是在特定实现上创建适用的性能基准。



简而言之,我希望这是 1 的情况,正在观察特定实现 string interning 的效果。



也就是说,文字中的所有字符串值(而不是字符串对象)都可以简单地嵌入到一个池中,以便 implIdentityEq(foo,foo)是true - 也就是说,只需要一个字符串对象。这样的实习可以在经常折叠之后进行,使得f+oo - > foo - 只要它支持ECMAScript语义,就再一次执行。



如果这样的实习完成,那么对于 implStringEq 第一个检查可以是评估 implIdentityEq(x,y),如果为true,比较是简单的并在O(1)中进行。如果为假,则需要进行正常的字符串字符比较,这是O(min(n,m))。



(也可以确定即时虚假与 x.length!= y.length ,但在这里似乎不那么相关。)






1 虽然在上面我认为字符串实习是一个可能的原因,现代JavaScript实现执行很多优化 - 因此,实习只是可以(并且已经完成)的各种优化和代码悬挂的一小部分



我' ve创建了一个 intern breakerjsperf 。数字符合上述假设。


  1. 如果一个字符串被实体,那么比较是测试性能的近似值对于身份,虽然比数字比较慢,但这比逐字符串比较要快得多。


  2. 持有上述断言,IE10似乎并没有考虑使用快速字符串比较的对象身份,尽管它使用快速失败长度检查。


  3. 在Chrome和Firefox中,两个不相等的国际字符串也被比较为两个 - 可能有两种不同的内部字符串之间的比较的特殊情况。


  4. 即使是小字符串(length = 8),实习也可以快得多。 IE10再次显示它没有这个优化,即使它似乎有一个有效的字符串比较实现。


  5. 字符串比较可能会失败,因为很快,因为遇到第一个不同的角色:即使比较长度相等的长串可能只比较前几个字符。








I'd like to write a little library for JavaScript enums. For me to do that, I need to decide how to store the enum values. Therefore, I'd like to use the fastest way when comparing, but I also want something that is debuggable, so I'm torn between using strings or numbers. I know I could use objects too, but that would be another question

For example

// I don't want this because when debugging, you'd see just the value 0
var Planets = {Earth:0, Mars:1, Venus: 2}

// I'd prefer this so that Planets.Earth gives me a nice readable value ("Earth")
var Planets = {Earth: 'Earth', Mars: 'Mars'}

But I'm afraid that when I compare them using if (myPlanet === Planet.Earth), the string comparison could take a lot longer (say if it were in a tight loop). This should be the case because http://ecma-international.org/ecma-262/5.1/#sec-11.9.6 says

If Type(x) is String, then return true if x and y are exactly the same sequence of characters (same length and same characters in corresponding positions); otherwise, return false.

But when I wrote a test case, I found that they take the same amount of time http://jsperf.com/string-comparison-versus-number-comparison/2 so it doesn't seem like it's scanning the whole string.

I know this could be a micro optimization, but my question is: is string equality comparison done using pointers and therefore just as fast as number equality comparison?

解决方案

String comparison could be "just as fast" (depending on implementation and values) - or it could be "much slower".

The ECMAScript specification describes the semantics, not the implementation. The only way to Know for Certain is to create an applicable performance benchmark on run it on a particular implementation.

Trivially, and I expect this is the case1, the effects of string interning for a particular implementation are being observed.

That is, all string values (not String Objects) from literals can be trivially interned into a pool such that implIdentityEq("foo", "foo") is true - that is, there need only one string object. Such interning can be done after constant folding, such that "f" + "oo" -> "foo" - again, per a particular implementation as long as it upholds the ECMAScript semantics.

If such interning is done, then for implStringEq the first check could be to evaluate implIdentityEq(x,y) and, if true, the comparison is trivially-true and performed in O(1). If false, then a normal string character-wise comparison would need to be done which is O(min(n,m)).

(Immediate falseness can also be determined with x.length != y.length, but that seems less relevant here.)


1 While in the above I argue for string interning being a likely cause, modern JavaScript implementations perform a lot of optimizations - as such, interning is only a small part of the various optimizations and code hoistings that can (and are) done!

I've created an "intern breaker" jsperf. The numbers agree with the hypothesis presented above.

  1. If a string is interned then comparison is approximate in performance to testing for "identity" - while it is slower than a numeric comparison, this is still much faster than a character-by-character string comparison.

  2. Holding the above assertion, IE10 does not appear to consider object-identity for pass-fast string comparisons although it does use a fast-fail length check.

  3. In Chrome and Firefox, two intern'ed strings which are not equal are also compared as quickly as two that are - there is likely a special case for comparing between two different interned strings.

  4. Even for small strings (length = 8), interning can be much faster. IE10 again shows it doesn't have this "optimization" even though it appears to have an efficient string comparison implementation.

  5. The string comparison can fail as soon as the first different character is encountered: even comparing long strings of equal length might only compare the first few characters.


  • Do common JavaScript implementations use string interning? (but no references given)

    Yes. In general any literal string, identifier, or other constant string in JS source is interned. However implementation details (exactly what is interned for instance) varies, as well as when the interning occurs

  • See JS_InternString (FF does have string interning, although where/how the strings are implicitly interened from JavaScript, I know not)

这篇关于JavaScript字符串的比较与数字比较一样快吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆