Friday, May 10, 2024
 Popular · Latest · Hot · Upcoming
191
rated 0 times [  193] [ 2]  / answers: 1 / hits: 16023  / 10 Years ago, fri, may 23, 2014, 12:00:00

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?


More From » string

 Answers
8

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)



[#70871] Thursday, May 22, 2014, 10 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
tiasavannahw

Total Points: 448
Total Questions: 122
Total Answers: 113

Location: Maldives
Member since Tue, Dec 21, 2021
2 Years ago
;