At the moment, incremental scheduler runs a repeating task in a while loop 
that checks if its duration has exceeded 16ms and then returns control to 
the browser.

If you assume that an incrementally scheduled task will tend to run in 
about the same time as it did before then you can get about a 10% speed up 
by counting the number of times the task ran during the last duration loop 
and then running the task that many times at the start (and skipping the 
duration check).

On chrome a task that calculated the fibonacci sequence managed to 
calculate about 450000 numbers in a second with the current scheduler and 
about 500000 numbers in the same time with my new one below.

And a realworld task that parses xml dropped from taking about 50 seconds 
each run to 42 seconds.

Of course if the incrementally scheduled task tends to take a longer and 
longer time to complete on each run the oprimization might cause issues so 
maybe we need to create a new kind of task scheduler specifically for tasks 
that tend to complete their runs in a similar timeframe.

I'm looking for critiscim of the code below, (and maybe someone to take 
ownership of this and do a PR to gerrit on my behalf)

In SchedulerImpl replace the current runRepeatingTasks method with this:  
(lastLoopCount is a private int field);

  /**
   * Execute a list of Tasks that hold RepeatingCommands.
   *
   * @return A replacement array that is possibly a shorter copy of 
<code>tasks</code>
   */
  private JsArray<Task> runRepeatingTasks(JsArray<Task> tasks) {
    assert tasks != null : "tasks";

    int length = tasks.length();
    if (length == 0) {
      return null;
    }

    boolean canceledSomeTasks = false;

    Duration duration = createDuration();
    int loopCount = 0;
    outer: while (duration.elapsedMillis() < TIME_SLICE) {
        
        if (length == 1) {
            while (lastLoopCount-- > 0 ) {
                 if (!tasks.get(0).executeRepeating()) {
                      tasks.set(0, null);
                      canceledSomeTasks = true;
                      break outer;
                 }
                 loopCount += 1;
            }
        }
      boolean executedSomeTask = false;
      for (int i = 0; i < length; i++) {
        assert tasks.length() == length : "Working array length changed " + 
tasks.length() + " != "
            + length;
        Task t = tasks.get(i);
        if (t == null) {
          continue;
        }
        executedSomeTask = true;

        assert t.isRepeating() : "Found a non-repeating Task";

        if (!t.executeRepeating()) {
          tasks.set(i, null);
          canceledSomeTasks = true;
        }
        loopCount += 1;
      }
      if (!executedSomeTask) {
        // no work left to do, break to avoid busy waiting until TIME_SLICE 
is reached
        break;
      }
    }
    if (length == 1) {
        lastLoopCount = loopCount;
    }

    if (canceledSomeTasks) {
        lastLoopCount = 0;
      JsArray<Task> newTasks = createQueue();
      // Remove tombstones
      for (int i = 0; i < length; i++) {
        if (tasks.get(i) != null) {
          newTasks.push(tasks.get(i));
        }
      }
      assert newTasks.length() < length;
      return newTasks.length() == 0 ? null : newTasks;
    } else {
      return tasks;
    }
  }

-- 
You received this message because you are subscribed to the Google Groups "GWT 
Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/google-web-toolkit-contributors/80297aa7-c49a-4e3b-b70a-554bfaef52f0%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to