| OLD | NEW |
| (Empty) | |
| 1 <script> |
| 2 var blobs = []; |
| 3 var bytes = 0; |
| 4 var timeStart; |
| 5 var timeEnd; |
| 6 var doneReading = false; |
| 7 var errors = []; |
| 8 var disableUI = false; |
| 9 |
| 10 function recordError(error) { |
| 11 console.log(error); |
| 12 errors.push(error); |
| 13 } |
| 14 |
| 15 function updateStats() { |
| 16 if (disableUI) return; |
| 17 var num_blobs = document.getElementById('num_blobs'); |
| 18 var total_bytes = document.getElementById('total_bytes'); |
| 19 var time = document.getElementById('time'); |
| 20 num_blobs.innerHTML = '' + blobs.length; |
| 21 total_bytes.innerHTML = '' + bytes; |
| 22 time.innerHTML = '' + (timeEnd - timeStart); |
| 23 } |
| 24 |
| 25 function createAndRead(size) { |
| 26 doneReading = false; |
| 27 errors = []; |
| 28 var reader = new FileReader(); |
| 29 var currentBlob = 0; |
| 30 var totalSize = 0; |
| 31 var error = document.getElementById('error'); |
| 32 var numRead = 0; |
| 33 |
| 34 console.time('Interaction.BlobCreateAndRead/repeatable'); |
| 35 var blob = new Blob([new Uint8Array(size)], {type: 'application/octet-string'}
); |
| 36 |
| 37 reader.onloadend = function(e) { |
| 38 console.timeEnd('Interaction.BlobCreateAndRead/repeatable'); |
| 39 if (reader.error) { |
| 40 recordError('Error when reading blob: ' + reader.error); |
| 41 doneReading = true; |
| 42 return; |
| 43 } |
| 44 if (reader.result.byteLength != size) { |
| 45 recordError("Sizes don't match"); |
| 46 } |
| 47 doneReading = true; |
| 48 } |
| 49 reader.readAsArrayBuffer(blob); |
| 50 } |
| 51 |
| 52 function createBlob(size) { |
| 53 timeStart = performance.now(); |
| 54 var blob = new Blob([new Uint8Array(size)], {type: 'application/octet-string'}
); |
| 55 timeEnd = performance.now(); |
| 56 blobs.push(blob); |
| 57 bytes += size; |
| 58 updateStats(); |
| 59 } |
| 60 |
| 61 function garbageCollect() { |
| 62 blobs = []; |
| 63 bytes = 0; |
| 64 updateStats(); |
| 65 } |
| 66 |
| 67 function addCustom() { |
| 68 var custom_input = document.getElementById('custom_input'); |
| 69 var custom_bytes = custom_input.value; |
| 70 createBlob(custom_bytes * 1); |
| 71 } |
| 72 |
| 73 function readBlobsSerially() { |
| 74 doneReading = false; |
| 75 errors = []; |
| 76 if (blobs.length == 0) { |
| 77 return; |
| 78 } |
| 79 timeStart = performance.now(); |
| 80 var reader = new FileReader(); |
| 81 var currentBlob = 0; |
| 82 var totalSize = 0; |
| 83 var error = document.getElementById('error'); |
| 84 var numRead = 0; |
| 85 reader.onloadend = function(e) { |
| 86 if (reader.error) { |
| 87 if (!disableUI) |
| 88 error.innerHTML += '<br/>Reader error:<br/>' + reader.error.message; |
| 89 recordError('Error when reading blob ' + currentBlob + ': ' + reader.error
); |
| 90 doneReading = true; |
| 91 return; |
| 92 } |
| 93 totalSize += reader.result.byteLength; |
| 94 currentBlob++; |
| 95 if (currentBlob < blobs.length) { |
| 96 reader.readAsArrayBuffer(blobs[currentBlob]); |
| 97 } else { |
| 98 timeEnd = performance.now(); |
| 99 // we're done reading |
| 100 if (totalSize != bytes) { |
| 101 recordError("Sizes don't match"); |
| 102 if (!disableUI) |
| 103 error.innerHTML += '<br/>Sizes don\'t match: ' + totalSize + ' vs ' +
bytes; |
| 104 } |
| 105 doneReading = true; |
| 106 updateStats(); |
| 107 } |
| 108 } |
| 109 reader.readAsArrayBuffer(blobs[currentBlob]); |
| 110 } |
| 111 function readBlobsInParallel() { |
| 112 doneReading = false; |
| 113 errors = []; |
| 114 if (blobs.length == 0) { |
| 115 return; |
| 116 } |
| 117 timeStart = performance.now(); |
| 118 var currentBlob = 0; |
| 119 var totalSize = 0; |
| 120 var error = document.getElementById('error'); |
| 121 var numRead = 0; |
| 122 for (; currentBlob < blobs.length; currentBlob++) { |
| 123 var genReader = function(index) { |
| 124 var reader = new FileReader(); |
| 125 reader.onloadend = function(e) { |
| 126 if (reader.error) { |
| 127 if (!disableUI) |
| 128 error.innerHTML += '<br/>Reader error:<br/>' + reader.error.message; |
| 129 recordError('Error when reading blob ' + index + ': ' + reader.error); |
| 130 doneReading = true; |
| 131 return; |
| 132 } |
| 133 totalSize += reader.result.byteLength; |
| 134 numRead++; |
| 135 if (numRead >= blobs.length) { |
| 136 timeEnd = performance.now(); |
| 137 // we're done reading |
| 138 if (totalSize != bytes) { |
| 139 recordError("Sizes don't match"); |
| 140 if (!disableUI) |
| 141 error.innerHTML += '<br/>Sizes don\'t match: ' + totalSize + ' vs
' + bytes; |
| 142 } |
| 143 doneReading = true; |
| 144 updateStats(); |
| 145 } |
| 146 } |
| 147 return reader; |
| 148 } |
| 149 genReader(currentBlob).readAsArrayBuffer(blobs[currentBlob]); |
| 150 } |
| 151 } |
| 152 </script> |
| 153 <div>Number of blobs: <span id="num_blobs">0</span>, total memory size: <span id
="total_bytes">0</span> bytes.</div> |
| 154 <input type="button" id="custom_input_submit" value="Add Blob with Size" onclick
="addCustom();"/> |
| 155 <input type="text" inputmode="numeric" id="custom_input" value=""/><br/> |
| 156 |
| 157 Shorcut buttons for person: |
| 158 <input type="button" value="2 bytes" onclick="createBlob(2);" /> |
| 159 <input type="button" value="1 kb" onclick="createBlob(1024);" /> |
| 160 <input type="button" value="16 kb" onclick="createBlob(16*1024);" /> |
| 161 <input type="button" value="1 mb" onclick="createBlob(1024 * 1024);" /> |
| 162 <input type="button" value="40 mb" onclick="createBlob(40 * 1024 * 1024);" /> |
| 163 <input type="button" value="400 mb" onclick="createBlob(400 * 1024 * 1024);" /> |
| 164 |
| 165 <input type="button" id="read_blobs_serial" value="Read Blobs Serially" onclick=
"readBlobsSerially();" /> |
| 166 <input type="button" id="read_blobs_parallel" value="Read Blobs Parallel" onclic
k="readBlobsInParallel();" /><br/> |
| 167 <input type="button" id="garbage_collect" value="Garbage Collect Blobs" onclick=
"garbageCollect();" /><br/> |
| 168 Operation Time: |
| 169 <div id="time"></div> |
| 170 Errors: |
| 171 <div id="error"></div> |
| OLD | NEW |