SitePoint Sponsor

User Tag List

Results 1 to 14 of 14
  1. #1
    secure webapps for all Aleksejs's Avatar
    Join Date
    Apr 2008
    Location
    Riga, Latvia
    Posts
    755
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Notice: This is a discussion thread for comments about the SitePoint article, Multi-threading in JavaScript.
    __________

    Really interesting article. I wonder if a full blown task scheduler could be implemented. :)

  2. #2
    SitePoint Guru Ize's Avatar
    Join Date
    Nov 2005
    Location
    The Netherlands
    Posts
    809
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for the article, James. This really made me think.
    I like how you always push the boundaries of Javascript, and are willing to share them.

  3. #3
    SitePoint Member
    Join Date
    Oct 2008
    Posts
    0
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I used this technique for QuiteBASIC. It is a Javascript interpreter for classic BASIC. In my first prototype, I broke up processing such that each program line (BASIC line) was processed separately. But it turns out that some browsers introduce a lot of overhead per timer invocation. So I ended up processing a number of lines at a time.

    I guess the lesson is that the chunks of processing should not be so big that they introduce UX unresponsiveness, but also not so small that the scheduling overhead becomes significant.

  4. #4
    Andrea Giammarchi
    SitePoint Community Guest
    This article could be interesting, but the usage of setInterval, instead of setTimeout, could makes things even worst.
    My humble suggestion is to read a couple of articles, as example from John Resig, about timings, and rethink some step.
    Best Regards

  5. #5
    breton
    SitePoint Community Guest
    yes that is a huge ungainly switch statement. You're repeating yourself an awful lot there. Wouldn't something like this be a bit more clever?

    function compute()
    {
    var move = null;

    var busy = false, task = 'init';
    var processor = setInterval(function()
    {
    if(!busy)
    {
    var tasktransitions = {
    init: ['tactic1','doit','tactic2'],
    tactic2:['tactic2','doit','tactic3'],
    tactic3:['tactic3','doit','pass'],
    doit:['doit','final'],
    pass:['pass','final'],
    final[clearInterval]
    }

    var arg = task==final?processor:undefined, par=tasktransitions[task];
    if(par) {
    move = window[par[0]](arg);
    if(move) { task = par[1] };
    else if(par[2]) {
    task = par[2];
    }
    }
    busy = false;
    }

    }, 100);
    }

  6. #6
    FBI secret agent digitman's Avatar
    Join Date
    Sep 2004
    Location
    Work
    Posts
    697
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Care to explain what your code is doing breton?

  7. #7
    Breton
    SitePoint Community Guest
    Oh sorry. I noticed that the switch statement's cases has a lot of code in common.

    here's one of them

    case 'init' :

    move = tactic1();
    if(move) { task = 'doit'; }
    else { task = 'tactic2'; }

    busy = false;
    break;


    essentially what each case is doing is this:

    case [taskname]:

    move = [var1]();
    if(move) { task = [var2]; }
    else { task = [var3]; }

    busy = false;
    break;


    so I made an object whose keys are tasks, (the thing the switch is switching on), and whose value is an array containing the values of [var1], [var2], and [var3].

    So I use the task to look up those variables, and I plug them into one common chunk of code. (this is unclear because it seems my function got corrupted when it was posted to the blog for some reason).

    and though it was not strictly speaking necessary, I added this
    var arg = task==final?processor:undefined, par=tasktransitions;

    To deal with a special case. ("final" is a bit different from the others).

  8. #8
    Breton
    SitePoint Community Guest
    So sorry, I just realized that this comment form will mangle my last comment as well. Here it is in pastebin form.

    pastebin.com/m8aad037

  9. #9
    SitePoint Author
    Join Date
    Jul 2005
    Posts
    3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    That's a cool idea James. It reminds me of this Actionscript multi-threading hack I came across when I was trying to figure out how to do pre-caching in Flash without affecting the framerate of an animation:

    blogs.adobe.com/aharui/2008/01/threads_in_actionscript_3.html

  10. #10
    SitePoint Zealot the DtTvB's Avatar
    Join Date
    Jul 2006
    Location
    Thailand
    Posts
    162
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Sometimes instead of setInterval, I use setTimeout, like this:

    Code:
    function task1() {
        // something here..
        setTimeout (task2, 1);
    }
    function task2() {
        // something here..
        setTimeout (task3, 1);
    }
    function task3() {
        // something here
    }
    And for some for loops or while loops, I created a simple script..

    Code:
    function myfor(obj) {
    	var time = 0;
    	function next() {
    		if (!obj.condition()) return;
    		time ++;
    		obj.body ();
    		obj.increment ();
    		setTimeout (next, 1);
    	}
    	obj.start ();
    	next ();
    }
    
    
    var i;
    var myloop = {
        start: function() { i = 0; },
        condition: function() { return i < 10000; },
        increment: function() { i ++; },
        body: function() {
        	document.title = i;
        }
    };
    myfor (myloop);
    This would work like a normal for loops, but instead of running everything all the thing once, it will run the loop body, wait for 1 millisecond to allow user to interact with the browser, and then run the body until the condition returns false.

    But some times using this is much slower because setTimeout was, well, sometimes be slower than just for loops.

    So... I made some changes to the next() function:

    Code:
    	function next() {
    		if (!obj.condition()) return;
    		time ++;
    		obj.body ();
    		obj.increment ();
    		if (time % 10 == 0)
    			setTimeout (next, 1);
    		else
    			next ();
    	}
    From what you see, the loop body will run at most 10 times at once, and then wait for a while, and then run the body 10 more times...

    I hope that this post will be useful!

  11. #11
    SitePoint Enthusiast
    Join Date
    Jan 2004
    Location
    Edinburgh, Scotland
    Posts
    90
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I too, would be interested in any comparisons with the efficiency of using setTimeOut(0) in a similar manner (which I have been known to do for large tasks.)

    I'm sure I read somewhere recently that the actual interval is unreliable in some browsers - does that affect the outcome?
    Throw away your Calculator -
    get instant results from www.calcResult.com

  12. #12
    breton
    SitePoint Community Guest
    "This would work like a normal for loops, but instead of running everything all the thing once, it will run the loop body, wait for 1 millisecond to allow user to interact with the browser, and then run the body until the condition returns false."

    The problem with this of course is that the minimum interval most browsers will give you is 10 milliseconds: a price the browser pays for running on top of an operating system.

    Google Chrome supposedly gets around this limitation though, I have no idea how.

    Per the difference between setTimeout and setInterval, as I understand it, they both generate events, which get put on a queue. Since a webpage basically runs in a single thread, only one event can be handled at a time, so the events on the queue just run in order, one after another- including the timers. Thus, the timer never executes EXACTLY in the interval you specify. The timer only generates an event exactly when you specify, and the event function itself only gets executed whenever the browser's single thread gets up to it in the queue. One additional consequence is that if a setInterval event happens, and there's already a setInterval event on the queue that hasn't been executed yet, the new event doesn't get added to the queue. So setInterval events get dropped. The smaller you set your interval, and the more complex your function, the more likely they are to get dropped.

    this doesn't happen with setTimeout however. Since the new setTimeout events don't get added until the last setTimeout function has finished, you never have more than one timer event on the queue at a time.

  13. #13
    reads the ********* Crier silver trophybronze trophy longneck's Avatar
    Join Date
    Feb 2004
    Location
    Tampa, FL (US)
    Posts
    9,854
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    hey, where's the game? i want to play.
    Check out our new Industry News forum!
    Keep up-to-date with the latest SP news in the Community Crier

    I edit the SitePoint Podcast

  14. #14
    SitePoint Member
    Join Date
    Feb 2011
    Posts
    1
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Brilliant! Yes, I have to do recursion too. I have a hierarchy of 7000 nodes and need to walk the tree in a loop. This solution makes it possible without freezing the browser. I did something similar for non-recursive loop on a canvas graph (9000+ points to graph) using setTimeout but I was having a brain-freeze on how to handle it with the recursive function call.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •