Javascript 在IndexedDB中,IDBObjectStore.put和IDBCursor.update之间有什么区别?

Javascript 在IndexedDB中,IDBObjectStore.put和IDBCursor.update之间有什么区别?,javascript,performance,indexeddb,Javascript,Performance,Indexeddb,在IndexedDB中,有两种方法可以更新数据库中已有的对象。您可以调用IDBCursor.update或IDBObjectStore.put 两者都接受更新的对象作为参数 IDBCursor.update要求您首先打开一个游标,但基本上您必须使用IDBObjectStore.put来检索先前的值 IDBObjectStore.put如果找不到要更新的对象,将创建一个新对象,但由于它必须先检查更新,我不知道这是否会实际产生性能差异 那么这些方法之间的区别是什么呢?我有什么遗漏吗?我试图制作一个测

在IndexedDB中,有两种方法可以更新数据库中已有的对象。您可以调用
IDBCursor.update
IDBObjectStore.put

两者都接受更新的对象作为参数

IDBCursor.update
要求您首先打开一个游标,但基本上您必须使用
IDBObjectStore.put
来检索先前的值

IDBObjectStore.put
如果找不到要更新的对象,将创建一个新对象,但由于它必须先检查更新,我不知道这是否会实际产生性能差异

那么这些方法之间的区别是什么呢?我有什么遗漏吗?我试图制作一个测试用例来调查性能差异:

var db;

function runTest(N, cb) {
  console.log("N = " + N);

  // Add some fake data to object store
  var tx = db.transaction("store", "readwrite");
  tx.objectStore("store").clear();
  for (var i = 0; i < N; i++) {
    tx.objectStore("store").add({"id": i, "index":0,"guid":"21310c91-ff31-4cb9-ae68-16d48cbbd84a","isActive":false,"balance":"$1,840.25","picture":"http://placehold.it/32x32","age":33,"eyeColor":"brown","name":"Witt Fletcher","gender":"male","company":"QUILM","email":"wittfletcher@quilm.com","phone":"+1 (851) 485-2174","address":"729 Conover Street, Marenisco, Virginia, 7219","about":"Incididunt do deserunt ut quis. Exercitation et ut ad aliqua ut do sint Lorem. Aliquip sit aliquip nulla excepteur pariatur ut laborum ea dolor. Consectetur incididunt et et esse commodo id eu dolor in. Nostrud sit mollit occaecat ullamco commodo aute anim duis enim et aliqua. Aute duis nostrud do minim labore sunt mollit in voluptate aliquip sit. Aliqua aliquip non ipsum exercitation cillum irure in.\r\n","registered":"2014-07-02T03:42:57 +04:00","latitude":-65.942119,"longitude":-129.471674,"tags":["reprehenderit","nostrud","velit","exercitation","nulla","nulla","est"],"friends":[{"id":0,"name":"Kristine Francis"},{"id":1,"name":"Lizzie Ruiz"},{"id":2,"name":"Bobbie Underwood"}],"greeting":"Hello, Witt Fletcher! You have 7 unread messages.","favoriteFruit":"apple"});
  }
  tx.oncomplete = function () {
    // Update with cursor.update
    var tStart = (new Date()).getTime();
    tx = db.transaction("store", "readwrite");
    var store = tx.objectStore("store");
    for (var i = 0; i < N; i++) {
      store.openCursor(i).onsuccess = function (event) {
        var cursor = event.target.result;
        cursor.value.age = 34;
        cursor.update(cursor.value);
      };
    }
    tx.oncomplete = function () {
      var tEnd = (new Date()).getTime();
      console.log("cursor.update - " + (tEnd - tStart) + " milliseconds");

      // Update with put
      tStart = (new Date()).getTime();
      tx = db.transaction("store", "readwrite");
      store = tx.objectStore("store");
      for (var i = 0; i < N; i++) {
        store.openCursor(i).onsuccess = function (event) {
          var cursor = event.target.result;
          cursor.value.age = 34;
          store.put(cursor.value);
        };
      }
      tx.oncomplete = function () {
        tEnd = (new Date()).getTime();
        console.log("put - " + (tEnd - tStart) + " milliseconds");

        if (cb !== undefined) {
          cb();
        }
      };
    };
  };
}

request = indexedDB.open("yes5ytrye", 1);
request.onerror = function (event) { console.log(event); };

request.onupgradeneeded = function (event) {
  var db = event.target.result;
  db.onerror = function (event) { console.log(event); };

  db.createObjectStore("store", {keyPath: "id"});
};

request.onsuccess = function (event) {
  db = request.result;
  db.onerror = function (event) { console.log(event); };

  runTest(100, function () {
    runTest(1000, function () {
      runTest(10000, function () {
        console.log("Done");
      });
    });
  });
};
性能基本上没有差别。当
N
较大时,铬的结果略有不同:

N = 100
cursor.update - 51 milliseconds
put - 44 milliseconds
N = 1000
cursor.update - 414 milliseconds
put - 447 milliseconds
N = 10000
cursor.update - 13506 milliseconds
put - 22783 milliseconds
Done

但正如我上面所说,我甚至不确定这两种方法之间是否应该有区别,因为它们似乎必须做完全相同的事情。

是的,它们在更新记录值的意义上是相同的。如果您已经知道键和值,请使用simple
put
,否则,只有使用稍微复杂的光标更新


更新记录的性能应该相同。

更新光标与放置光标之间的主要区别在于,您需要检索要使用光标更新的元素;另一方面,当使用
put
语句时,您只需要知道正在更新的元素的
id
,只需执行
put
函数,该函数是在
store
级别定义的。但是,这种加速仅在将完整对象存储在内存中的情况下有效

我对您的代码进行了一些更新,加快了速度:

var-db;
函数运行测试(N,cb){
console.log(“N=”+N);
//向对象存储添加一些伪数据
var tx=数据库事务(“存储”、“读写”);
tx.objectStore(“store”).clear();
对于(变量i=0;iN = 100
cursor.update - 51 milliseconds
put - 44 milliseconds
N = 1000
cursor.update - 414 milliseconds
put - 447 milliseconds
N = 10000
cursor.update - 13506 milliseconds
put - 22783 milliseconds
Done