简体   繁体   English

切片/合并Blob的渐近复杂度

[英]Asymptotic complexity of slicing/merging blobs

I want to work heavily with JavaScript blobs. 我想大量使用JavaScript Blob。 But I'm not sure about performance of some operations. 但是我不确定某些操作的性能。 So in this simple example... 所以在这个简单的例子中...

let n = 10; // not a constant :-)
let blob = e.dataTransfer.files[0]; // some file from user...

let blob1 = blob.slice(0, n); // O(1) or O(n)?
let blob2 = blob.slice(n); // O(1), O(n), O(blob2.length) or O(blob.length)?
let merged = new Blob([blob1, blob2]); // O(1) or O(blob.length)?

URL.createObjectURL(merged); // O(blob.length) - just to ensure, that blob will be used...

I'm interested in both time and space complexity. 我对时间和空间的复杂性都感兴趣。

Each function has different implementation for each engine. 每个功能对每个引擎都有不同的实现。
For WebKit you can check slice here: 对于WebKit,您可以在此处检查切片:
https://github.com/WebKit/webkit/blob/master/Source/WebCore/platform/network/BlobRegistryImpl.cpp#L182 https://github.com/WebKit/webkit/blob/master/Source/WebCore/platform/network/BlobRegistryImpl.cpp#L182
For Firefox it's somwhere here: 对于Firefox,它在这里:
https://hg.mozilla.org/mozilla-central/file/d8e238b811d3/dom/file https://hg.mozilla.org/mozilla-central/file/d8e238b811d3/dom/file
Also it can be changed with new version. 也可以使用新版本进行更改。
So the best way is to try with the real data in real browsers and to measure results. 因此,最好的方法是在实际的浏览器中尝试使用真实的数据并衡量结果。 Then you will be able to decide. 这样您就可以决定了。

And as I see from source code for WebKit, Blob.slice is O(blob.length) even if you have startIndex and endIndex. 从WebKit的源代码中可以看到,即使您具有startIndex和endIndex,Blob.slice仍为O(blob.length)。
Blob([b1,b2..]) is O(b1.length + b2.length + ...) Blob([b1,b2 ..])是O(b1.length + b2.length + ...)
But URL.createObjectURL is just generate link to Blob, so it's O(1). 但是URL.createObjectURL只是生成到Blob的链接,所以它是O(1)。

Blob is immutable, so every time you are changing Blob you are creating new one. Blob是不可变的,因此每次更改Blob时,您都在创建一个新的Blob。 That's why you can't just get reference to part of Blob with slice. 这就是为什么您不能仅通过切片引用Blob的一部分。

To play with Blobs I created this code: 为了玩Blob,我创建了以下代码:

var container = document.getElementById('container');
var getReaderPromise = function(bl) {
  var blReader = new FileReader();
  return new Promise(function(resolve, reject) {
    blReader.onload = function() { resolve(blReader.result) };
    blReader.readAsArrayBuffer(bl);
  });
}

var showContent = function(arrbuf) {
  console.log(String.fromCharCode.apply(null, new Uint8Array(arrbuf)));
}

var foo = new Blob('abcdefghjklmnopqrstuvwxyz'.split(''), {type : 'text/plain'});
var promiseFoo = getReaderPromise(foo);
var foores = undefined;
promiseFoo.then(function(res) {
  foores = res;
});

var bar1 = foo.slice(2,10);
var promiseBar1 = getReaderPromise(bar1);
var bar1res = undefined;
promiseBar1.then(function(res) {
  bar1res = res;
});

var bar2 = foo.slice(12,20);
var promiseBar2 = getReaderPromise(bar2);
var bar2res = undefined;
promiseBar2.then(function(res) {
  bar2res = res;
});

var bars = new Blob([bar1, bar2]);
var promiseBars = getReaderPromise(bars);
var barsres = undefined;
promiseBars.then(function(res) {
  barsres = res;
});

Promise.all([promiseFoo, promiseBar1, promiseBar2, promiseBars]).then(function() {
  showContent(foores);
  showContent(bar1res);
  showContent(bar2res);
  showContent(barsres);

  var bar2arr = new Uint8Array(bar2res);
  bar2arr[4] = '2'.charCodeAt();

  showContent(bar2res);
  showContent(barsres);
  showContent(foores);


  var url = URL.createObjectURL(bars);
  console.log(url);
  container.innerHTML += '<iframe src="' + url + '"></iframe>';
  var barsarr = new Uint8Array(barsres);
  barsarr[4] = '5'.charCodeAt();
  container.innerHTML +=  '<iframe src="' + url + '"></iframe>';
  url = URL.createObjectURL(bars);
  console.log(url);
  container.innerHTML += '<iframe src="' + url + '"></iframe>';
});

( http://www.kurilo.su/stackoverflow/46085675/ ) http://www.kurilo.su/stackoverflow/46085675/
You can try to open it in different browsers and will find that Blob is immutable in any browsers. 您可以尝试在不同的浏览器中打开它,并且会发现Blob在任何浏览器中都是不可变的。
So slice and merge can't be O(1). 因此,切片和合并不能为O(1)。 At least O(n), but as I can see in WebKit it's O(blob.length). 至少为O(n),但正如我在WebKit中所看到的那样,它为O(blob.length)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM