ArrayBuffer/String conversion (v19)

Revision 19 of this benchmark created on


Setup

var veryLongStr = "ECMAScript [ECMA-262] has traditionally been used in contexts where there is no access to binary data. Where binary data has needed to be manipulated, it is often stored as a String and accessed using charCodeAt(), or stored as an Array with conversion to and from base64 for transmission. Both of these methods are slow and error-prone. For example, reading binary data as 32-bit integers requires manual conversion of 4 source bytes to and from the target type. Reading floating-point data is even more expensive. As web applications gain access to new functionality, working with binary data has become a much-demanded feature. Current specifications such as the File API [FILEAPI] and Web Sockets [WEBSOCKETS] would benefit from being able to read and write binary data directly in its native form. Specifications such as WebGL [WEBGL] require this functionality to meet acceptable performance characteristics. This specification defines a minimal set of functionality for accessing binary data from ECMAScript.";
    
    var shortStr = "This specification provides an API for interoperability with native binary data. It defines a generic fixed-length buffer type, as well as accessor types that allow access to the data stored within the buffer.";
    
    var buffer = new ArrayBuffer(veryLongStr.length * 2);
    var dataview = new DataView(buffer);
    
    var latinStr = "áàãçñôéôã";
    
    var ab2str_blobreader = function(buf, callback) {
        var blob;
        BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder;
        if (typeof(BlobBuilder) !== 'undefined') {
          var bb = new BlobBuilder();
          bb.append(buf);
          blob = bb.getBlob();
        } else {
          blob = new Blob([buf]);
        }
        var f = new FileReader();
        f.onload = function(e) {
            callback(e.target.result)
        }
        f.readAsText(blob);
    }    
        
    var str2ab_blobreader = function(str, callback) {
        var blob;
        BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder;
        if (typeof(BlobBuilder) !== 'undefined') {
          var bb = new BlobBuilder();
          bb.append(str);
          blob = bb.getBlob();
        } else {
          blob = new Blob([str]);
        }
        var f = new FileReader();
        f.onload = function(e) {
            callback(e.target.result)
        }
        f.readAsArrayBuffer(blob);
    }
    
    
    var ab2str_arraymanipulation = function(buf) {
        var bufView = new Uint16Array(buf);
        var unis = Array.prototype.slice.call(bufView);
        return String.fromCharCode.apply(null, unis);
        }
        
    
    var str2ab_arraymanipulation = function(str) {
        var buf = new ArrayBuffer(str.length * 2);
        var bufView = new Uint16Array(buf);
        for (var i = 0; i < str.length; i++) {
          bufView[i] = str.charCodeAt(i);
        }
        return buf;
        }
    
    var strtoab = function(dataview, start, string) {
        // Check for buffer overflow eventually ?
        
        for (var i = 0; i < string.length; i++) {
          dataview.setUint16(start + (i * 2), string.charCodeAt(i));
        }
    }
    
    var abtostr = function(dataview, start, length) {
        var unis = [];
        
        for (var i = 0; i < length; i++) {
          unis.push(dataview.getUint16(start + (i*2)));
        }
        
        return String.fromCharCode.apply(null, unis);
    }

Test runner

Ready to run.

Testing in
TestOps/sec
BlobReader/FileReader
// async test
str2ab_blobreader(veryLongStr, function(ab) {
  ab2str_blobreader(ab, function(str) {
    if (str !== veryLongStr) {
      throw "expected=" + veryLongStr + " but got " + str;
    }
    deferred.resolve();
  });
});
ready
Direct array manipulation
var ab = str2ab_arraymanipulation(veryLongStr);
var str = ab2str_arraymanipulation(ab);
if (str !== veryLongStr) {
  throw "expected=" + veryLongStr + " but got " + str;
}
ready
My method
strtoab(dataview, 0, veryLongStr);
var str = abtostr(dataview, 0, veryLongStr.length);

if (str !== veryLongStr) {
  throw "expected=" + veryLongStr + " but got " + str;
}
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.