Is the Javascript String length constant time?

后端 未结 6 2151
萌比男神i
萌比男神i 2020-12-18 20:15

I\'m fairly new to JS, and realize length is considered a property. But I received a comment to not use str.length in a loop:

for (i=0; i

相关标签:
6条回答
  • 2020-12-18 20:51

    Is str.length guaranteed constant time in JS too?

    No, in fact there are no runtime performance or complexity guarantees in JavaScript whatsoever.

    However, yes, it can be expected to be accessible in constant time, with no dynamic linear time length computation on access. The ECMAScript spec also describes the String .length property as immutable and that it is initialised when the string is constructed.

    0 讨论(0)
  • 2020-12-18 20:56

    The question seems to have been well answered, but here's another 2¢ which may be helpful.

    Using string.length can cause unexpected behavior in for loops if the string is overwritten by something with a different length inside the loop e.g:

    var k = "abcabcabc";
    for(var i=0; i<k.length; i++){
      k=k.slice(0,-1);
      console.log(k);
    }
    

    Will log "abcabcab", "abcabca", ... , "abca" and then stop because the length is changing.

    Of course, this may be intentional, in which case go for it (although arguably you should use a while loop).

    0 讨论(0)
  • 2020-12-18 20:57

    Length is an instance property and it's constant time

    It must be implement a string with a given length that is represented as a contiguous, zero-terminated array of jschars. It does this by explicitly storing a length and a pointer to the zero-terminated array

    Explicitly stored is the indicator here that it's constant time.

    Read How Strings Are Implemented In SpiderMonkey for more info on how Firefox implements strings.

    0 讨论(0)
  • 2020-12-18 21:01

    Strings are also immutable in JavaScript. The length property does not need to be computed each time it is accessed.

    I created a jsperf benchmark for you to view here.

    You'll notice the speeds are the same.

    0 讨论(0)
  • 2020-12-18 21:06

    W3Schools recommends that you use this:

    l = arr.length;
    for (i = 0; i < l; i++) {..}
    

    instead of this:

    for (i = 0; i < arr.length; i++) {...}
    

    Claiming that:

    The bad code accesses the length property of an array each time the loop is iterated.

    The better code accesses the length property outside the loop, and makes the loop run faster.


    Is it better to store frequently accessed values in a local variable?

    Because w3schools is evil, let me quote from another source (Writing Efficient JavaScript - Nicholas C. Zakas).

    ... The important lesson to take from this information is to always store frequently accessed values in a local variable. Consider the following code:

    function process(data){
        if (data.count > 0){
            for (var i=0; i < data.count; i++){
                processData(data.item[i]);
            }
        }
    }
    

    ...The function will run faster if this value is stored in a local variable and then accessed from there:

    function process(data){
        var count = data.count;
        if (count > 0){
            for (var i=0; i < count; i++){
    
                processData(data.item[i]);
            }
        }
    }
    

    Why property accessing is slower than accessing instance variables?

    From here:

    Most JavaScript engines use a dictionary-like data structure as storage for object properties - each property access requires a dynamic lookup to resolve the property's location in memory. This approach makes accessing properties in JavaScript typically much slower than accessing instance variables in programming languages like Java and Smalltalk.


    Why performance benchmarking doesn't show any differences?

    In general some (or most) JavaScript engines use optimization techniques to improve the property access time like this one by V8.

    Also, JavaScript string objects might be of a different nature as you cannot add properties dynamically to them. (which makes the dynamic lookup unnecessary.. I guess)


    Conclusion

    For string.length use any of the two code snippets. But for other object types or properties that do computations, then you have to benchmark your code performance first (or just store the value in a local variable).

    0 讨论(0)
  • 2020-12-18 21:08

    In any language that has immulate strings, whether Java, JavaScript, C# or others, it will be a very bad practice by the creators of the language NOT to provide a "constant time" "length" operation for a string.
    Since the string is immutable, its length cannot change, hence all it is required is to store the length of the string upon creation in some field inside the string object and return it upon calling to the "length" propery/method.

    0 讨论(0)
提交回复
热议问题