Beware of implicit object conversion (v6)

Revision 6 of this benchmark created by Kyle Simpson on


Description

Taken from: http://dev.opera.com/articles/view/efficient-javascript/

Literals, such as strings, numbers, and boolean values, have two representations within ECMAScript. Each of them can be created as either a value or an object. For example, a string value is created simply by saying var oString = 'some content';, while an equivalent string object is created by saying var oString = new String('some content');. Any properties and methods are defined on the string object, not the value. When you reference a property or method of a string value, the ECMAScript engine must implicitly create a new string object with the same value as your string, before running the method. This object is only used for that one request, and will be recreated next time you attempt to use a method of the string value. This example requires the script engine to create 21 new string objects, once for each time the length property is accessed, and once each time the charAt method is called: var s = '0123456789'; for( var i = 0; i < s.length; i++ ) { s.charAt(i); } This equivalent example creates just a single object, and will perform better as a result: var s = new String('0123456789'); for( var i = 0; i < s.length; i++ ) { s.charAt(i); } If your code calls methods of literal values very often, you should consider converting them into objects instead, as in the previous example. Note that although most of the points in this article are relevant to all browsers, this particular optimization is aimed mainly at Opera. It may also affect some other browsers, but can be a little slower in Internet Explorer and Firefox.

Setup

var s1 = 'abcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefg';
    var s2 = new String('abcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefcabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefg');
    var l = s2.length;
    var i;
    var tmp = new Array(l);

Test runner

Ready to run.

Testing in
TestOps/sec
simple string
for (i = 0; i < l; i++) {
  tmp[i] = s1.charAt(i);
}
ready
String object
for (i = 0; i < l; i++) {
  tmp[i] = s2.charAt(i);
}
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.

  • Revision 1: published by Matthew O'Donoghue on
  • Revision 3: published by Kyle Simpson on
  • Revision 6: published by Kyle Simpson on