(function (d, w, undefined) { var ww = new Worker(getInlineJS()); var tresholdselector = d.querySelector('#treshold'); var print = Helpers.log2Screen; var chunkMssg = d.querySelector("#chunking"); var chunks = function () { var div = d.createElement('div'); d.body.appendChild(div); return div; }(); var chunk = function () { var span = d.createElement('span'); span.className = "numbers"; return span; }(); var nchunks; tresholdselector.addEventListener('change', start); start(); ww.onmessage = function (e) { // status message during calculation if (e.data.status) { return print( 'still working ... found <code>' + e.data.found + '</code> prime numbers', {clear: true, direct: true} ); } // chunked writing for large result set if (e.data.chunk) { var nwChunk = chunk.cloneNode(); nwChunk.innerHTML = '<br>' + e.data.chunk; chunks.appendChild( nwChunk ); chunkMssg.textContent = e.data.text; } $('#warning').addClass('hidden'); // print result print( e.data.msg, ', calculation took ', e.data.duration, ' millisecond', e.data.duration != 1 ? 's': '', '<br><b>Prime numbers found</b>:<br>', {clear:true} ); // if n of primes > 10000 write them in chunks of 1000 to screen, // using the webworker. Else just write to screen. if( e.data.primes && e.data.primes.length > 10000 ) { nchunks = Math.floor(e.data.primes.length/250) + 1; ww.postMessage({writechunked: e.data.primes, nchunks: nchunks}); } else { print('<br><div class="numbers">',e.data.primes.join(' '), '</div>'); } }; function start() { chunks.innerHTML = ""; chunkMssg.textContent = ""; print('start working...', {clear:true, direct: true}); $('#warning')[+tresholdselector.value > 100000 ? 'removeClass' : 'addClass']('hidden'); ww.postMessage({value: tresholdselector.value}); } function getInlineJS() { var ecmaCode = d.querySelector('[data-isworker]').textContent ,ecmaBlob = new Blob([ecmaCode], {"type": "application\/javascript"}); return URL.createObjectURL(ecmaBlob); } }(document, window))
<div class="solink" data-linkid="26312971"></div> <h3>Using a web worker to calculate prime numbers from 0 to [Threshold]</h3> <p id="warning" class="hidden">This may take a while (but the browser is not blocked)</p> <p id="chunking"></p> Threshold: <select id="treshold"> <option value="10">10</option> <option value="100" selected="selected">100</option> <option value="1000">1000</option> <option value="10000">10000</option> <option value="100000">100000</option> <option value="1000000">1000000</option> <option value="10000000">10000000</option> <option value="100000000">100000000</option> </select> <script type="text/ecmaworker" data-isworker="true"> String.prototype.padLeft = String.prototype.padLeft || function padLeft(base, chr) { var len = (String(base || 10).length - String(this).length) + 1; return len > 0 ? new Array(len).join(chr || '0') + this : this; }; Number.prototype.pretty = function (usa, noprecision){ var somenum = this ,dec = (''+somenum).split(/[.,]/) ,lendec = dec[1] ? dec[1].length : 0 ,precision = lendec && !noprecision ? decPrecise(somenum,lendec) : dec[1] ,sep = usa ? ',' : '.' ,decsep = usa ? '.' : ','; // from http://stackoverflow.com/questions/10473994/javascript-adding-decimal-numbers-issue/10474209 function decPrecise(d,l){ return String(d.toFixed(12)).split(/[.,]/)[1].substr(0,l); } function xsep(num,sep) { var n = String(num).split('') ,i = -3; while (n.length + i > 0) { n.splice(i, 0, sep); i -= 4; } return n.join(''); } return xsep(dec[0],sep) + (dec[1] ? decsep+precision :''); } onmessage = function (e) { if (e.data.writechunked) { var arr = e.data.writechunked.slice(0); var chunknr = 0; do { chunknr += 1; postMessage({chunk: arr.splice(0, 250).join(" "), chunknr: chunknr, text: 'Written chunk # ' + chunknr +' of ' + e.data.nchunks}); } while (arr.length); return; } var n = 0 ,total = 0 ,THRESHOLD = +e.data.value ,startTime = new Date ,primes = []; while (++n < THRESHOLD) { var isprime = isPrime(n); total += isprime ? 1 : 0; void( isprime && (primes.push(String(n).padLeft(Math.floor(THRESHOLD/10), ' ')), primes.length % 100 < 1 && postMessage({status: true, found: primes.length})) ); } postMessage({ msg: 'Found <code>' + total.pretty(1) + '</code> prime numbers using threshold <code>' + THRESHOLD.pretty(1) + '</code>', primes: primes, duration: (new Date - startTime).pretty(1)}); function isPrime(number) { var start = 2; while (start <= Math.sqrt(number)) { if (number % start++ < 1) return false; } return number > 1; } } </script>
#warning { color: red; font-weight: bold; } .hidden { display: none; } .numbers { font-family: courier new; }