GithubHelp home page GithubHelp logo

Comments (11)

max99x avatar max99x commented on July 24, 2024

Could you provide some benchmarks showing improvements resulting from async code?

from emscripten.

yuguang avatar yuguang commented on July 24, 2024

after running some benchmarks using benchmark.js, it looks like they have the same performance as using a for loop.

from emscripten.

max99x avatar max99x commented on July 24, 2024

It appears this can be closed then.

from emscripten.

yuguang avatar yuguang commented on July 24, 2024

I found a real async function. The benchmark result is that async is 4x faster because the num array has length 4 and they all finish at the same time.

<html>

    <head>
        <script type='text/javascript' src='benchmark.js'>
        </script>
        <script type='text/javascript' src='jquery-1.4.4.min.js'>
        </script>
    </head>

    <body>
        <script>
            var suite = new Benchmark.Suite;

            var Queue = (function() {

                function make() {
                    var results = [],
                        stack = [],
                        queue = [];

                    function buildControl(queue) {
                        var obj = {
                            next: function() {
                                obj.next = function() {};
                                stack.shift();

                                var first = stack[0];
                                if (first) {
                                    first(buildControl(queue));
                                } else {
                                    queue();
                                }
                            }
                        };
                        return obj;
                    }

                    var obj = {
                        make: make,

                        sync: function(func) {
                            if (typeof func === "function") {
                                stack.push(func);

                                if (stack.length === 1) {
                                    func(buildControl(obj.async()));
                                }
                            }
                        },

                        async: function(func) {
                            var index = queue.push(func) - 1;

                            return function() {
                                if (index === null) {
                                    return;
                                }

                                results[index] = Array.prototype.slice.call(arguments);
                                index = null;

                                for (var i = 0; i < queue.length; i += 1) {
                                    if (results[i]) {
                                        if (typeof queue[i] === "function") {
                                            queue[i].apply(null, results[i]);
                                            delete queue[i];
                                        }
                                    } else {
                                        return;
                                    }
                                }

                                queue.length = results.length = 0;
                            };
                        },

                        run: function(func) {
                            return obj.async(func)();
                        }
                    };
                    return obj;
                }

                return make();
            }());

            nums = [];
            for (var i = 0; i < 4; i++) {
                nums.push(i);
            }

            // add tests
            suite.add('async', function() {
                nums.forEach(Queue.async(function(num) {
                    for (var i = 0; i < 100; i++) {
                        $('#pad').text(i * 5 * num);
                    }
                }));
            }).add('linear', function() {
                for (var i = 0; i < 4; i++) {
                    for (var j = 0; j < 100; j++) {
                        $('#pad').text(j * 5 * nums[i]);
                    }
                }
            })
            // add listeners
            .on('cycle', function(event, bench) {
                console.log(String(bench));
            }).on('complete', function() {
                console.log('Fastest is ' + this.filter('fastest').pluck('name'));
            })
            // run async
            .run(true);
        </script>
        <div id="pad">
        </div>
    </body>

</html>

it requires benchmark.js and jquery

from emscripten.

amasad avatar amasad commented on July 24, 2024

Your 'async' test is under executing.
The Queus.async call would run only once, in comparison with the 'linear' test the inner loop would execute once instead of 4 times.
Consider the following:

        nums.forEach(function (n) {
            Queue.async(function(num) {
                for (var i = 0; i < 100; i++) {
                    $('#pad').text(i * 5 * num);
                }
            })(n);
        })

Given that there is nothing async (a callback that would basically run with an empty call stack) about the 'async' test they're basically the same with the same score.

from emscripten.

yuguang avatar yuguang commented on July 24, 2024

The forEach loop iterates through each item in the array. If you want to try both of them with forEach:

nums = [];
for (var i = 0; i < 5; i++) {
    nums.push(i);
}

// add tests
suite.add('async', function() {
    nums.forEach(Queue.async(function(num) {
        for (var i = 0; i < 100; i++) {
            $('#pad').text(i * 5 * num);
        }
    }));
}).add('linear', function() {
    nums.forEach(function(num) {
        for (var j = 0; j < 100; j++) {
            $('#pad').text(j * 5 * num);
        }
    });
})
// add listeners
.on('cycle', function(event, bench) {
    console.log(String(bench));
}).on('complete', function() {
    console.log('Fastest is ' + this.filter('fastest').pluck('name'));
})
// run async
.run(true);

Original Queue code from http://kaescripts.blogspot.com/2010/02/asynchronous-callbacks-in-javascript.html. You are correct in observing that it only takes the amount of time of one iteration of the loop through nums. That is because they are executed asynchronously and all finish at the same time.

from emscripten.

amasad avatar amasad commented on July 24, 2024
nums.forEach(Queue.async(function(num) {
    for (var i = 0; i < 100; i++) {
        $('#pad').text(i * 5 * num);
    }
}));

Its wrong!

Queue.async would just run once, for illustration consider the body of the function is collapsed:

nums.forEach(Queue.async(function (){...}));

It would push one function to the Queue and return a function that would be used as an iterator for all the forEach loop, and since there is one function the queue, the iterator would return without running each time except for the first time at the following if in the returned function from Queue.async

                   return function() {

                        if (index === null) {
                            return;
                        }
                        ....

from emscripten.

amasad avatar amasad commented on July 24, 2024

The following benchmark includes the corrected forEach iterator, and gets rid of DOM calls since we are not testing the DOM: http://jsperf.com/avq1/2

The what so called 'async' test is titled Q and the 'linear' is titled L, L runs faster on all browsers.

from emscripten.

yuguang avatar yuguang commented on July 24, 2024

You're right. It looks like the only way to do asynchronous scripting may be with async=true on the script tag when loading scripts.

from emscripten.

amasad avatar amasad commented on July 24, 2024

There is nothing called asynchronous scripting, given that JS runs in a single threaded environment it can't allow to block. Hence all blocking calls (disk, network ..etc) registers an event in what is called an event-loop which is responsible for registering event listeners that would be executed once the event they listen to has fired, thus giving it the asynchronous nature.

$.get(url, function (res) { //do some stuff});

This would make an asynchrounus http request that would register an event in the event loop and attatch the callback as an event listener, once the request has completed and the results are in, the callback would run.

nimble and async would just help you manage your async calls and would not run your calls concurrently as you assumed.

from emscripten.

yuguang avatar yuguang commented on July 24, 2024

If javascript really did support asynchronous execution, then it should be well documented.

from emscripten.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.