[OpenLayers-Dev] Re: [OpenLayers 3] type instantiation performance

Xavier Mamano (jorix) xavier.mamano at gmail.com
Thu Oct 21 14:03:22 EDT 2010



Eric Lemoine-2-2 wrote:
> 
> I did some experiments to compare the various alternatives to creating
> objects.
> 
> The results: using object litterals yields better performance in IE7,
> FF3, FF4, and Safari 3, but not in Chrome. And IE is the browser where
> using object litterals really pays off. The numbers also show the
> performance penalty incurred when using OpenLayers.Class.
> 
> The performance numbers, in milliseconds (small is better):
> 
> IE7
> -----
> OpenLayers.Class 1289
> Pure JavaScript 547
> Object Litteral 296.5
> 
> FF3
> ------
> OpenLayers.Class 188.05
> Pure JavaScript 85.15
> Object Litteral 79.5
> 
> FF4
> ------
> OpenLayers.Class 73.5
> Pure JavaScript 33.1
> Object Litteral 22.15
> 
> Chrome 6
> --------------
> OpenLayers.Class 9.3
> Pure JavaScript 2.45
> Object Litteral 4.6
> 
> Safari 3
> -----------
> OpenLayers.Class 19.45
> Pure JavaScript 8.7
> Object Litteral 6.3
> 
> ...
> _______________________________________________
> Dev mailing list
> Dev at lists.osgeo.org
> http://lists.osgeo.org/mailman/listinfo/openlayers-dev
> 
> 
Hi,

I tested the time on my computer, the results are similar. To emphasize that
"Class" is made even worse.

I tried also the times of the object pixel+prototype, do not vary
significantly compared with those of pixel1 and pixel2.

Curiously: Pixel6 (with options as the only argument) double the time of
Pixel5 (with the arguments x and y).

A reflection: will be problems if the code attempts to use methods of an
object created only as an object literal. For example try using Pixel.offset
or Pixel.add break the code execution. Should be documented well where can
use object literals and where not.

IE 8.0.6
    OpenLayers.Class; 1512.4
    Pure JavaScript; 541.5
    Object Litteral; 417.1
    OpenLayers.Pixel; 2103.8
    Pure JavaScript Pixel; 563.2
    Pure JavaScript Pixel using argument options; 894.0

FF 3.6.11 + Firebug
    OpenLayers.Class; 1123.1
    Pure JavaScript; 114.4
    Object Litteral; 77.3
    OpenLayers.Pixel; 1407.5
    Pure JavaScript Pixel; 111.3
    Pure JavaScript Pixel using argument options; 256.6

Safari 5.0.2
    OpenLayers.Class; 652.5
    Pure JavaScript; 41.3
    Object Litteral; 39.3
    OpenLayers.Pixel; 803.2
    Pure JavaScript Pixel; 39.1
    Pure JavaScript Pixel using argument options; 78.3

Chrome 6.0.4
    OpenLayers.Class; 112.8
    Pure JavaScript; 6.7
    Object Litteral; 7.7
    OpenLayers.Pixel; 307.1
    Pure JavaScript Pixel; 6.5
    Pure JavaScript Pixel using argument options; 13.9

Attached the code I used.

Note: The complexity of the "avg" function is due to have detected high
peaks in the samples. I can give explanations on merits of "avg".

<!DOCTYPE html>
<html debug="true">
    <head>
    <script src="../lib/Firebug/firebug.js"></script>
    <script src="../OpenLayers.js"></script>
    <script>
        var Pixel1 = OpenLayers.Class({
            initialize: function(x, y) {
                this.x = x;
                this.y = y;
            }
        });

        var Pixel2 = function(x, y) {
            this.x = x; this.y = y;
        };

        var Pixel5 = function(x, y) {
            this.x = x;
            this.y = y;
        };
        Pixel5.prototype = {
            x:0.0,
            y:0.0,
            toString:function(){return ("x=" + this.x + ",y=" + this.y);},
            clone:function(){return new OpenLayers.Pixel(this.x, this.y);},
            equals:function(px){var equals = false;if (px != null) {equals =
((this.x == px.x && this.y == px.y) ||(isNaN(this.x) && isNaN(this.y) &&
isNaN(px.x) && isNaN(px.y)));}return equals;},
            add:function(x, y){if((x == null)||(y == null)){var msg =
OpenLayers.i18n("pixelAddError");OpenLayers.Console.error(msg);return
null;}return new OpenLayers.Pixel(this.x + x, this.y + y);},
            offset:function(px){var newPx = this.clone();if (px) {newPx =
this.add(px.x, px.y);}return newPx;},
            CLASS_NAME:"OpenLayers.Pixel5"
        };

        var Pixel6 = function(options) {
            this.x = options.x;
            this.y = options.y;
        };
        Pixel6.prototype = {
            x:0.0,
            y:0.0,
            toString:function(){return ("x=" + this.x + ",y=" + this.y);},
            clone:function(){return new OpenLayers.Pixel(this.x, this.y);},
            equals:function(px){var equals = false;if (px != null) {equals =
((this.x == px.x && this.y == px.y) ||(isNaN(this.x) && isNaN(this.y) &&
isNaN(px.x) && isNaN(px.y)));}return equals;},
            add:function(x, y){if((x == null)||(y == null)){var msg =
OpenLayers.i18n("pixelAddError");OpenLayers.Console.error(msg);return
null;}return new OpenLayers.Pixel(this.x + x, this.y + y);},
            offset:function(px){var newPx = this.clone();if (px) {newPx =
this.add(px.x, px.y);}return newPx;},
            CLASS_NAME:"OpenLayers.Pixel6"
        };

        function avg(testName,times) {
            var t = times.slice(0);
            t = t.sort(function (a,b){return a - b;}); // sort ascending
            var ev;
            while (true) {
                ev = staValues(t);
                if (ev.avg == 0 ||    // break if all values are 0
                    ev.nsd <= 0.5 ||   // clean up of the normalized
standard deviation is less than 0.5
                    ev.l <= times.length * 2/3 // remove 1/3 of the sample
maximum.
                    ) {
                    break;
                }
                console.log(testName+";", ev.avg.toFixed(1), "; max;",
t[ev.l-1], "; nsd;", ev.nsd.toFixed(3), "; sample;", ev.l); // to monitor
cleaning
                t.pop(); // remove the anomalous peak produced by the
garbage collect or other
                t.shift(); // remove the minimum to balance the sample
            }
            console.log(testName+";", ev.avg.toFixed(1));
        }
        function staValues(t) {
            var s = 0, v=0;
            for(var i=0, l=t.length; i<l; i++) {
                s += t[i];
                v += t[i]*t[i];
            }
            var ev ={};
            ev.avg = (s/l);
            // Normalized standard deviation
            ev.nsd = Math.sqrt((v/l)-(ev.avg*ev.avg))/ev.avg; 
            ev.l = l;
            return ev;
        }

        var NUM = 30;
        var ITERATIONS = 100000;
        var i, j, l, start, stop, p, times = new Array(NUM);

        // case 1
        for(i=0; i<NUM; i++) {
            start = new Date;
            for(j=0; j<ITERATIONS; j++) {
                p = new Pixel1(23.4, 42.4);
            }
            stop = new Date;
            times[i] = stop.getTime()-start.getTime();
        }
        avg("OpenLayers.Class", times);

        // case 2
        for(i=0; i<NUM; i++) {
            start = new Date;
            for(j=0; j<ITERATIONS; j++) {
                p = new Pixel2(23.4, 42.4);
            }
            stop = new Date;
            times[i] = stop.getTime()-start.getTime();
        }
        avg("Pure JavaScript",times);

        // case 3
        for(i=0; i<NUM; i++) {
            start = new Date;
            for(j=0; j<ITERATIONS; j++) {
                p = {x: 23.4, y: 42.4};
            }
            stop = new Date;
            times[i] = stop.getTime()-start.getTime();
        }
        avg("Object Litteral",times);

        // case 4
        for(i=0; i<NUM; i++) {
            start = new Date;
            for(j=0; j<ITERATIONS; j++) {
                p = new OpenLayers.Pixel(23.4, 42.4);
            }
            stop = new Date;
            times[i] = stop.getTime()-start.getTime();
        }
        avg("OpenLayers.Pixel",times);

        // case 5
        for(i=0; i<NUM; i++) {
            start = new Date;
            for(j=0; j<ITERATIONS; j++) {
                p = new Pixel5(23.4, 42.4);
            }
            stop = new Date;
            times[i] = stop.getTime()-start.getTime();
        }
        avg("Pure JavaScript Pixel",times);

        // case 6
        for(i=0; i<NUM; i++) {
            start = new Date;
            for(j=0; j<ITERATIONS; j++) {
                p = new Pixel6({x:23.4, y:42.4});
            }
            stop = new Date;
            times[i] = stop.getTime()-start.getTime();
        }
        avg("Pure JavaScript Pixel using argument options",times);

    </script>
    </head>
    <body>
    </body>
</html> 


-- 
View this message in context: http://osgeo-org.1803224.n2.nabble.com/OpenLayers-3-type-instantiation-performance-tp5641805p5659677.html
Sent from the OpenLayers Dev mailing list archive at Nabble.com.


More information about the Dev mailing list