4

I'm planning on writing some code for encrypting files in javascript locally. For large files and large key sizes, the CPU usage (naturally) is pretty high. In a single script design, this often hangs the browser until the task is complete.

In order to improve responsiveness and allow users to do other things in the mean time I want to try make the script 'friendlier' to the user's PC. The encryption process will be reading a file as a binary string and then encrypting the string in chunks (something like 1KB/chunk - needs testing). I want to try and user HTML5-based workers to make the whole thing as incremental as possible. Something like:

  1. Spawn worker
  2. Send worker a binary data chunk
  3. Worker completes encryption, passes back new chunk
  4. Worker dies.

This might also help with multicore processors, by having multiple workers alive at once.

Anyway, has anybody looked at deliberately slowing down a script in order to reduce CPU usage? Something like splitting the worker's encryption task into single operations, and introducing a delay between them.

Interval timer callback every 100ms (example).

Is worker busy?
Yes - Wait for another interval
No - Start encrypting the next letter

Advice/thoughts?

Does anyone have experience using workers? If you seperate the main UI from intensieve work by making it a worker, does the responsiveness increase?

Oliver
  • 1,395
  • 1
  • 14
  • 33

1 Answers1

2

This doesn't utilize anything HTML5, but here's an example for calling a function every N milliseconds, assuming you can determine an appropriate wait time. Basically, I'm trying to help you by showing you a way to enforce stalling some amount of time before doing more processing.

function doSomething(){
   clearTimeout(timeout);
   // do your "expensive" processing
   // ...
   // decide the job is done and return here or else
   // call doSomething again in sleepMS milliseconds
   timeout = setTimeout(doSomething,sleepMS);
}
var timeout;
var sleepMS = 1000;


doSomething();

EDIT

changed last line from

var timeout = setTimeout(doSomething,1000);

to just this

doSomething()

EDIT 2

Changed 1000 to sleepMS in setTimeout call, duh :)

mrk
  • 4,999
  • 3
  • 27
  • 42
  • This is what I was thinking of. And introducing this delay will have the net effect of reducing the overall CPU usuage, and not hang the browser (although slowing down the total encryption time)? – Oliver Jul 27 '11 at 15:19
  • Right, this is a roundabout way of reducing CPU usage because (without any ActiveX or other plugin) JS doesn't give you direct access to processor time on CPU. Here's another trick that can help, http://stackoverflow.com/questions/5177451/measure-processing-time-of-ajax-call which could also be useful for your task – mrk Jul 27 '11 at 15:37
  • maybe you meant setTimeout(doSomething,sleepMS); at the end of the function? – Jose Faeti Jul 27 '11 at 15:47
  • Warning: variable timeout is declared but never used. Warning: variable sleepMS is declared but never used. – Joshua Carmody Jul 27 '11 at 15:49
  • I'm interpreting it as pseudocode so don't worry about the exact syntax. I'm going to do some experiments continously encrypting, and varying the delay between each encryption cycle and its effect on the browser. @mrk I'm not sure how the ajax timing post applies to this, care to elaborate? – Oliver Jul 27 '11 at 15:54
  • Deleted my previous comments, went off on the wrong tangent. I included the ajax timing post just as view to a different way of looking at things. For example, you could calculate doSomething processing time on each call and weight the sleepMS time based on faster/slower processing. – mrk Jul 27 '11 at 16:08
  • If I assume that whilst running the encryption task, the CPU is working at 100%; then by introducing a delay the same length as the encryption took I'll get a 50% duty cycle (thats right, I'm an electronic engineer). I played around with it a little and found that even adding a very little delay helps the responsiveness alot, even if the CPU usage is still high. – Oliver Jul 27 '11 at 18:55
  • 2
    Encrypting a 1024 byte string seem to take around 250ms on a mediocre, so I think just by ensuring only one worker is active at a time and introducing a small delay between killing the previous and generating the next will ensure enough CPU time for other processes. Its a shame/missing feature that browsers don't take a more active roll in controlling javascript CPU usage. Apps are getting more intensieve, and more likely to work locally in javascript. – Oliver Jul 27 '11 at 18:59