Re: [gwt-contrib] Incremental Scheduler can be about 10% faster

2015-01-14 Thread Thomas Broyer
Also, your approach is assuming that all tasks in the queue are the same 
task that needs repeating. But what if I schedule 2 incremental tasks?

On Wednesday, January 14, 2015 at 3:07:47 PM UTC+1, Richard Wallis wrote:

 Just an update, there's a bug in my original implementation which causes 
 the loopCounter to tend to increase until the task ends.

 After removing the bug, the performance increase is only about 8% for the 
 fibonacci sequence.

 Also the safer version where the loopCounter increments by at most 1 
 eliminates the performance gain for the fibonacci test because the task 
 runs 8000 to 9000 times during each loop so the loopCounter never gets 
 anywhere close to a number that will make a difference.


 On Wed, Jan 14, 2015 at 2:19 PM, Richard Wallis rdwal...@gmail.com 
 wrote:

 Actually in defense of adding the optimization to the current api.

 It can be made safe by only ever setting lastLoopCounter to 
 min(lastLoopCounter + 1, loopCounter).

 That should cause similar improved performance for multiple second tasks 
 without ever having a lower frame rate than the current scheduler.

 On Wed, Jan 14, 2015 at 1:41 PM, Richard Wallis rdwal...@gmail.com 
 wrote:

 You can't use webworkers to process the dom / xml, or do layout which is 
 pretty much all my long running tasks do.

 Agree this is too dangerous to just add to the existing api but if you 
 added a new method scheduleConstantTime() that ran the optimization it 
 might be useful.


 On Wed, Jan 14, 2015 at 1:27 PM, 'Daniel Kurka' via GWT Contributors 
 google-web-toolkit-contributors@googlegroups.com wrote:

 I think we do not want to make any assumptions about runtime of any 
 tasks since this would not work well with task that have variable runtime.

 If you need to do heavy calculations since browser APIs have evolved a 
 lot you should be using web workers anyway.

 On Wed, Jan 14, 2015 at 11:57 AM, Richard Wallis rdwal...@gmail.com 
 wrote:

 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 45 numbers in a second with the current scheduler and 
 about 50 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 
 codetasks/code
*/
   private JsArrayTask runRepeatingTasks(JsArrayTask 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;
   

Re: [gwt-contrib] Incremental Scheduler can be about 10% faster

2015-01-14 Thread Richard Wallis
Still very much a draft but I've settled on two approaches:

Calculating the fibonacci sequence either approach performs about 5x better
than the curent scheduler.

Fibonacci sequence is thousands of very short operations so it does very
well the more the duration check is skipped.  Real world tasks won't
improve nearly as much but I think most code should get a 10 to 15% speed
increase.

First approach skips loops based on how many times it ran last time (This
is faster than second but I think more dangerous and only works if you're
running a single task):

  private int lastLoopCount;
  /**
   * Execute a list of Tasks that hold RepeatingCommands.
   *
   * @return A replacement array that is possibly a shorter copy of
codetasks/code
   */
  private JsArrayTask runRepeatingTasks(JsArrayTask tasks) {
assert tasks != null : tasks;

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

boolean canceledSomeTasks = false;

Duration duration = createDuration();

int loopCount = lastLoopCount;
boolean skipLoop = false;
if (length == 1  lastLoopCount  0) {
while (lastLoopCount--  0 ) {
 if (!tasks.get(0).executeRepeating()) {
  tasks.set(0, null);
  canceledSomeTasks = true;
 }
}
skipLoop = canceledSomeTasks || duration.elapsedMillis() =
TIME_SLICE;
}
if (skipLoop) {
lastLoopCount -= 2;
} else {
  while (duration.elapsedMillis()  TIME_SLICE) {

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;
  JsArrayTask 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;
}
  }

Second approach checks how much time is elapsed and how many times the task
has been run and then calculates how many times the task can be run before
it needs to check the elapsed time again.  (This is very slightly slower
than the above but can be made to work with multiple tasks and I think will
be easier to make safe, although isn't safe at the moment):

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

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

boolean canceledSomeTasks = false;

Duration duration = createDuration();
int runCount = 0;
int quickRunCount = 0;
int elapsedMillis = duration.elapsedMillis();
while ( elapsedMillis  TIME_SLICE) {

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;
}

}
if (!executedSomeTask) {
// no work left to do, break to avoid busy waiting until
// TIME_SLICE is reached
break;
}
runCount += 1;
if (quickRunCount-- = 0) {
elapsedMillis = duration.elapsedMillis();
if (elapsedMillis  0) {
quickRunCount = (int) (((TIME_SLICE - 1) * runCount) /
elapsedMillis);
}
}

}

if (canceledSomeTasks) {
JsArrayTask newTasks = createQueue();
// Remove tombstones
for (int i = 0; i  length; i++) {
if (tasks.get(i) != null) {
   

Re: [gwt-contrib] Incremental Scheduler can be about 10% faster

2015-01-14 Thread Richard Wallis
Ah second implementation has a bug again that makes it much faster than it
should be I'll post the fix and the actual speed up, if any, shortly.

On Wed, Jan 14, 2015 at 5:34 PM, Richard Wallis rdwal...@gmail.com wrote:

 On a side note the Scheduler implentation needs to be rewritten to make it
 easier to provide alternative schedulers while letting those alternative
 schedulers use as much of the core code as possible.

 It would be easier to make these patches if runRepeatingTasks was
 protected and there was a Scheduler interface instead of an abstract class
 with so many nested classes.


 On Wed, Jan 14, 2015 at 5:25 PM, Richard Wallis rdwal...@gmail.com
 wrote:

 Also, your approach is assuming that all tasks in the queue are the same
 task that needs repeating. But what if I schedule 2 incremental tasks?


 Loop count code takes this into account and only runs if the length of
 the task queue == 1.

 The second approach where you divide the TIME_SLICE by elapsed time and
 then multiply by how many tasks have run will work with multiple tasks at a
 time.  It's dangerous in the current implementation because the faster job
 can die before a slower job messing up the estimate.  But it can be made
 safe

 On Wed, Jan 14, 2015 at 5:14 PM, Thomas Broyer t.bro...@gmail.com
 wrote:

 Also, your approach is assuming that all tasks in the queue are the
 same task that needs repeating. But what if I schedule 2 incremental tasks?


 On Wednesday, January 14, 2015 at 3:07:47 PM UTC+1, Richard Wallis wrote:

 Just an update, there's a bug in my original implementation which
 causes the loopCounter to tend to increase until the task ends.

 After removing the bug, the performance increase is only about 8% for
 the fibonacci sequence.

 Also the safer version where the loopCounter increments by at most 1
 eliminates the performance gain for the fibonacci test because the task
 runs 8000 to 9000 times during each loop so the loopCounter never gets
 anywhere close to a number that will make a difference.


 On Wed, Jan 14, 2015 at 2:19 PM, Richard Wallis rdwal...@gmail.com
 wrote:

 Actually in defense of adding the optimization to the current api.

 It can be made safe by only ever setting lastLoopCounter to
 min(lastLoopCounter + 1, loopCounter).

 That should cause similar improved performance for multiple second
 tasks without ever having a lower frame rate than the current scheduler.

 On Wed, Jan 14, 2015 at 1:41 PM, Richard Wallis rdwal...@gmail.com
 wrote:

 You can't use webworkers to process the dom / xml, or do layout which
 is pretty much all my long running tasks do.

 Agree this is too dangerous to just add to the existing api but if
 you added a new method scheduleConstantTime() that ran the optimization 
 it
 might be useful.


 On Wed, Jan 14, 2015 at 1:27 PM, 'Daniel Kurka' via GWT Contributors
 google-web-toolkit-contributors@googlegroups.com wrote:

 I think we do not want to make any assumptions about runtime of any
 tasks since this would not work well with task that have variable 
 runtime.

 If you need to do heavy calculations since browser APIs have evolved
 a lot you should be using web workers anyway.

 On Wed, Jan 14, 2015 at 11:57 AM, Richard Wallis rdwal...@gmail.com
  wrote:

 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 45 numbers in a second with the current scheduler 
 and
 about 50 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
 codetasks/code
*/
   private JsArrayTask runRepeatingTasks(JsArrayTask tasks) {
 assert tasks != null : tasks;

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

 boolean canceledSomeTasks = false;

 Duration 

Re: [gwt-contrib] Incremental Scheduler can be about 10% faster

2015-01-14 Thread Richard Wallis
On a side note the Scheduler implentation needs to be rewritten to make it
easier to provide alternative schedulers while letting those alternative
schedulers use as much of the core code as possible.

It would be easier to make these patches if runRepeatingTasks was protected
and there was a Scheduler interface instead of an abstract class with so
many nested classes.


On Wed, Jan 14, 2015 at 5:25 PM, Richard Wallis rdwal...@gmail.com wrote:

 Also, your approach is assuming that all tasks in the queue are the same
 task that needs repeating. But what if I schedule 2 incremental tasks?


 Loop count code takes this into account and only runs if the length of the
 task queue == 1.

 The second approach where you divide the TIME_SLICE by elapsed time and
 then multiply by how many tasks have run will work with multiple tasks at a
 time.  It's dangerous in the current implementation because the faster job
 can die before a slower job messing up the estimate.  But it can be made
 safe

 On Wed, Jan 14, 2015 at 5:14 PM, Thomas Broyer t.bro...@gmail.com wrote:

 Also, your approach is assuming that all tasks in the queue are the same
 task that needs repeating. But what if I schedule 2 incremental tasks?


 On Wednesday, January 14, 2015 at 3:07:47 PM UTC+1, Richard Wallis wrote:

 Just an update, there's a bug in my original implementation which causes
 the loopCounter to tend to increase until the task ends.

 After removing the bug, the performance increase is only about 8% for
 the fibonacci sequence.

 Also the safer version where the loopCounter increments by at most 1
 eliminates the performance gain for the fibonacci test because the task
 runs 8000 to 9000 times during each loop so the loopCounter never gets
 anywhere close to a number that will make a difference.


 On Wed, Jan 14, 2015 at 2:19 PM, Richard Wallis rdwal...@gmail.com
 wrote:

 Actually in defense of adding the optimization to the current api.

 It can be made safe by only ever setting lastLoopCounter to
 min(lastLoopCounter + 1, loopCounter).

 That should cause similar improved performance for multiple second
 tasks without ever having a lower frame rate than the current scheduler.

 On Wed, Jan 14, 2015 at 1:41 PM, Richard Wallis rdwal...@gmail.com
 wrote:

 You can't use webworkers to process the dom / xml, or do layout which
 is pretty much all my long running tasks do.

 Agree this is too dangerous to just add to the existing api but if you
 added a new method scheduleConstantTime() that ran the optimization it
 might be useful.


 On Wed, Jan 14, 2015 at 1:27 PM, 'Daniel Kurka' via GWT Contributors 
 google-web-toolkit-contributors@googlegroups.com wrote:

 I think we do not want to make any assumptions about runtime of any
 tasks since this would not work well with task that have variable 
 runtime.

 If you need to do heavy calculations since browser APIs have evolved
 a lot you should be using web workers anyway.

 On Wed, Jan 14, 2015 at 11:57 AM, Richard Wallis rdwal...@gmail.com
 wrote:

 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 45 numbers in a second with the current scheduler 
 and
 about 50 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
 codetasks/code
*/
   private JsArrayTask runRepeatingTasks(JsArrayTask 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 

Re: [gwt-contrib] Incremental Scheduler can be about 10% faster

2015-01-14 Thread Richard Wallis

 It's dangerous in the current implementation because the faster job can
 die before a slower job messing up the estimate.


The above is wrong, any task finishing will make the estimate too low
(which is safe) rather than too high.

On Wed, Jan 14, 2015 at 5:25 PM, Richard Wallis rdwal...@gmail.com wrote:

 Also, your approach is assuming that all tasks in the queue are the same
 task that needs repeating. But what if I schedule 2 incremental tasks?


 Loop count code takes this into account and only runs if the length of the
 task queue == 1.

 The second approach where you divide the TIME_SLICE by elapsed time and
 then multiply by how many tasks have run will work with multiple tasks at a
 time.  It's dangerous in the current implementation because the faster job
 can die before a slower job messing up the estimate.  But it can be made
 safe

 On Wed, Jan 14, 2015 at 5:14 PM, Thomas Broyer t.bro...@gmail.com wrote:

 Also, your approach is assuming that all tasks in the queue are the same
 task that needs repeating. But what if I schedule 2 incremental tasks?


 On Wednesday, January 14, 2015 at 3:07:47 PM UTC+1, Richard Wallis wrote:

 Just an update, there's a bug in my original implementation which causes
 the loopCounter to tend to increase until the task ends.

 After removing the bug, the performance increase is only about 8% for
 the fibonacci sequence.

 Also the safer version where the loopCounter increments by at most 1
 eliminates the performance gain for the fibonacci test because the task
 runs 8000 to 9000 times during each loop so the loopCounter never gets
 anywhere close to a number that will make a difference.


 On Wed, Jan 14, 2015 at 2:19 PM, Richard Wallis rdwal...@gmail.com
 wrote:

 Actually in defense of adding the optimization to the current api.

 It can be made safe by only ever setting lastLoopCounter to
 min(lastLoopCounter + 1, loopCounter).

 That should cause similar improved performance for multiple second
 tasks without ever having a lower frame rate than the current scheduler.

 On Wed, Jan 14, 2015 at 1:41 PM, Richard Wallis rdwal...@gmail.com
 wrote:

 You can't use webworkers to process the dom / xml, or do layout which
 is pretty much all my long running tasks do.

 Agree this is too dangerous to just add to the existing api but if you
 added a new method scheduleConstantTime() that ran the optimization it
 might be useful.


 On Wed, Jan 14, 2015 at 1:27 PM, 'Daniel Kurka' via GWT Contributors 
 google-web-toolkit-contributors@googlegroups.com wrote:

 I think we do not want to make any assumptions about runtime of any
 tasks since this would not work well with task that have variable 
 runtime.

 If you need to do heavy calculations since browser APIs have evolved
 a lot you should be using web workers anyway.

 On Wed, Jan 14, 2015 at 11:57 AM, Richard Wallis rdwal...@gmail.com
 wrote:

 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 45 numbers in a second with the current scheduler 
 and
 about 50 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
 codetasks/code
*/
   private JsArrayTask runRepeatingTasks(JsArrayTask 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;

Re: [gwt-contrib] Incremental Scheduler can be about 10% faster

2015-01-14 Thread Richard Wallis
Fixing the bug didn't change the performance noticably:

Bug fix is:

quickRunCount = (int) (((TIME_SLICE - 1) * runCount) / elapsedMillis);

becomes:

quickRunCount = (int) (((TIME_SLICE - 1) * runCount) / elapsedMillis) -
runCount;

On Wed, Jan 14, 2015 at 5:37 PM, Richard Wallis rdwal...@gmail.com wrote:

 Ah second implementation has a bug again that makes it much faster than it
 should be I'll post the fix and the actual speed up, if any, shortly.

 On Wed, Jan 14, 2015 at 5:34 PM, Richard Wallis rdwal...@gmail.com
 wrote:

 On a side note the Scheduler implentation needs to be rewritten to make
 it easier to provide alternative schedulers while letting those alternative
 schedulers use as much of the core code as possible.

 It would be easier to make these patches if runRepeatingTasks was
 protected and there was a Scheduler interface instead of an abstract class
 with so many nested classes.


 On Wed, Jan 14, 2015 at 5:25 PM, Richard Wallis rdwal...@gmail.com
 wrote:

 Also, your approach is assuming that all tasks in the queue are the
 same task that needs repeating. But what if I schedule 2 incremental 
 tasks?


 Loop count code takes this into account and only runs if the length of
 the task queue == 1.

 The second approach where you divide the TIME_SLICE by elapsed time and
 then multiply by how many tasks have run will work with multiple tasks at a
 time.  It's dangerous in the current implementation because the faster job
 can die before a slower job messing up the estimate.  But it can be made
 safe

 On Wed, Jan 14, 2015 at 5:14 PM, Thomas Broyer t.bro...@gmail.com
 wrote:

 Also, your approach is assuming that all tasks in the queue are the
 same task that needs repeating. But what if I schedule 2 incremental 
 tasks?


 On Wednesday, January 14, 2015 at 3:07:47 PM UTC+1, Richard Wallis
 wrote:

 Just an update, there's a bug in my original implementation which
 causes the loopCounter to tend to increase until the task ends.

 After removing the bug, the performance increase is only about 8% for
 the fibonacci sequence.

 Also the safer version where the loopCounter increments by at most 1
 eliminates the performance gain for the fibonacci test because the task
 runs 8000 to 9000 times during each loop so the loopCounter never gets
 anywhere close to a number that will make a difference.


 On Wed, Jan 14, 2015 at 2:19 PM, Richard Wallis rdwal...@gmail.com
 wrote:

 Actually in defense of adding the optimization to the current api.

 It can be made safe by only ever setting lastLoopCounter to
 min(lastLoopCounter + 1, loopCounter).

 That should cause similar improved performance for multiple second
 tasks without ever having a lower frame rate than the current scheduler.

 On Wed, Jan 14, 2015 at 1:41 PM, Richard Wallis rdwal...@gmail.com
 wrote:

 You can't use webworkers to process the dom / xml, or do layout
 which is pretty much all my long running tasks do.

 Agree this is too dangerous to just add to the existing api but if
 you added a new method scheduleConstantTime() that ran the optimization 
 it
 might be useful.


 On Wed, Jan 14, 2015 at 1:27 PM, 'Daniel Kurka' via GWT Contributors
 google-web-toolkit-contributors@googlegroups.com wrote:

 I think we do not want to make any assumptions about runtime of any
 tasks since this would not work well with task that have variable 
 runtime.

 If you need to do heavy calculations since browser APIs have
 evolved a lot you should be using web workers anyway.

 On Wed, Jan 14, 2015 at 11:57 AM, Richard Wallis 
 rdwal...@gmail.com wrote:

 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 45 numbers in a second with the current scheduler 
 and
 about 50 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 

Re: [gwt-contrib] Incremental Scheduler can be about 10% faster

2015-01-14 Thread Richard Wallis
You can't use webworkers to process the dom / xml, or do layout which is
pretty much all my long running tasks do.

Agree this is too dangerous to just add to the existing api but if you
added a new method scheduleConstantTime() that ran the optimization it
might be useful.


On Wed, Jan 14, 2015 at 1:27 PM, 'Daniel Kurka' via GWT Contributors 
google-web-toolkit-contributors@googlegroups.com wrote:

 I think we do not want to make any assumptions about runtime of any tasks
 since this would not work well with task that have variable runtime.

 If you need to do heavy calculations since browser APIs have evolved a lot
 you should be using web workers anyway.

 On Wed, Jan 14, 2015 at 11:57 AM, Richard Wallis rdwal...@gmail.com
 wrote:

 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 45 numbers in a second with the current scheduler and
 about 50 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
 codetasks/code
*/
   private JsArrayTask runRepeatingTasks(JsArrayTask 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;
   JsArrayTask 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 google-web-toolkit-contributors+unsubscr...@googlegroups.com.
 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
 https://groups.google.com/d/msgid/google-web-toolkit-contributors/80297aa7-c49a-4e3b-b70a-554bfaef52f0%40googlegroups.com?utm_medium=emailutm_source=footer
 .
 For more options, visit https://groups.google.com/d/optout.




 --
 Google Germany GmbH
 *Dienerstr. 12*
 *80331 München*

 Registergericht und -nummer: Hamburg, HRB 86891
 Sitz der Gesellschaft: Hamburg
 Geschäftsführer: Graham Law, Katherine Stephens

 --
 You received this message because you are subscribed to the 

Re: [gwt-contrib] Incremental Scheduler can be about 10% faster

2015-01-14 Thread 'Daniel Kurka' via GWT Contributors
I think we do not want to make any assumptions about runtime of any tasks
since this would not work well with task that have variable runtime.

If you need to do heavy calculations since browser APIs have evolved a lot
you should be using web workers anyway.

On Wed, Jan 14, 2015 at 11:57 AM, Richard Wallis rdwal...@gmail.com wrote:

 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 45 numbers in a second with the current scheduler and
 about 50 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
 codetasks/code
*/
   private JsArrayTask runRepeatingTasks(JsArrayTask 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;
   JsArrayTask 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 google-web-toolkit-contributors+unsubscr...@googlegroups.com.
 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
 https://groups.google.com/d/msgid/google-web-toolkit-contributors/80297aa7-c49a-4e3b-b70a-554bfaef52f0%40googlegroups.com?utm_medium=emailutm_source=footer
 .
 For more options, visit https://groups.google.com/d/optout.




-- 
Google Germany GmbH
*Dienerstr. 12*
*80331 München*

Registergericht und -nummer: Hamburg, HRB 86891
Sitz der Gesellschaft: Hamburg
Geschäftsführer: Graham Law, Katherine Stephens

-- 
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 google-web-toolkit-contributors+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/google-web-toolkit-contributors/CALLujipuOFMxCnLjdM_FER4n3-eAHPEWUQGf3AZENR_ezq255A%40mail.gmail.com.
For more options, visit 

[gwt-contrib] Incremental Scheduler can be about 10% faster

2015-01-14 Thread Richard Wallis
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 45 numbers in a second with the current scheduler and 
about 50 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 
codetasks/code
   */
  private JsArrayTask runRepeatingTasks(JsArrayTask 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;
  JsArrayTask 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 google-web-toolkit-contributors+unsubscr...@googlegroups.com.
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.


Re: [gwt-contrib] Incremental Scheduler can be about 10% faster

2015-01-14 Thread Richard Wallis
Actually in defense of adding the optimization to the current api.

It can be made safe by only ever setting lastLoopCounter to
min(lastLoopCounter + 1, loopCounter).

That should cause similar improved performance for multiple second tasks
without ever having a lower frame rate than the current scheduler.

On Wed, Jan 14, 2015 at 1:41 PM, Richard Wallis rdwal...@gmail.com wrote:

 You can't use webworkers to process the dom / xml, or do layout which is
 pretty much all my long running tasks do.

 Agree this is too dangerous to just add to the existing api but if you
 added a new method scheduleConstantTime() that ran the optimization it
 might be useful.


 On Wed, Jan 14, 2015 at 1:27 PM, 'Daniel Kurka' via GWT Contributors 
 google-web-toolkit-contributors@googlegroups.com wrote:

 I think we do not want to make any assumptions about runtime of any tasks
 since this would not work well with task that have variable runtime.

 If you need to do heavy calculations since browser APIs have evolved a
 lot you should be using web workers anyway.

 On Wed, Jan 14, 2015 at 11:57 AM, Richard Wallis rdwal...@gmail.com
 wrote:

 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 45 numbers in a second with the current scheduler and
 about 50 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
 codetasks/code
*/
   private JsArrayTask runRepeatingTasks(JsArrayTask 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;
   JsArrayTask 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 google-web-toolkit-contributors+unsubscr...@googlegroups.com
 .
 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
 

Re: [gwt-contrib] Incremental Scheduler can be about 10% faster

2015-01-14 Thread Richard Wallis
Just an update, there's a bug in my original implementation which causes
the loopCounter to tend to increase until the task ends.

After removing the bug, the performance increase is only about 8% for the
fibonacci sequence.

Also the safer version where the loopCounter increments by at most 1
eliminates the performance gain for the fibonacci test because the task
runs 8000 to 9000 times during each loop so the loopCounter never gets
anywhere close to a number that will make a difference.


On Wed, Jan 14, 2015 at 2:19 PM, Richard Wallis rdwal...@gmail.com wrote:

 Actually in defense of adding the optimization to the current api.

 It can be made safe by only ever setting lastLoopCounter to
 min(lastLoopCounter + 1, loopCounter).

 That should cause similar improved performance for multiple second tasks
 without ever having a lower frame rate than the current scheduler.

 On Wed, Jan 14, 2015 at 1:41 PM, Richard Wallis rdwal...@gmail.com
 wrote:

 You can't use webworkers to process the dom / xml, or do layout which is
 pretty much all my long running tasks do.

 Agree this is too dangerous to just add to the existing api but if you
 added a new method scheduleConstantTime() that ran the optimization it
 might be useful.


 On Wed, Jan 14, 2015 at 1:27 PM, 'Daniel Kurka' via GWT Contributors 
 google-web-toolkit-contributors@googlegroups.com wrote:

 I think we do not want to make any assumptions about runtime of any
 tasks since this would not work well with task that have variable runtime.

 If you need to do heavy calculations since browser APIs have evolved a
 lot you should be using web workers anyway.

 On Wed, Jan 14, 2015 at 11:57 AM, Richard Wallis rdwal...@gmail.com
 wrote:

 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 45 numbers in a second with the current scheduler and
 about 50 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
 codetasks/code
*/
   private JsArrayTask runRepeatingTasks(JsArrayTask 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;
   JsArrayTask 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() ==