2014-12-14 14 views
5

In IndexedDB, ci sono due modi per aggiornare un oggetto già nel database. È possibile chiamare IDBCursor.update o IDBObjectStore.put.In IndexedDB, qual è la differenza tra IDBObjectStore.put e IDBCursor.update?

Entrambi accettano l'oggetto aggiornato come parametro.

IDBCursor.update richiede di aprire un cursore per primo, ma in pratica è necessario farlo con IDBObjectStore.put anche per recuperare il valore precedente.

IDBObjectStore.put creerà un nuovo oggetto se non riesce a trovarne uno da aggiornare, ma poiché deve verificare prima un aggiornamento, non so se questo creerebbe effettivamente una differenza di prestazioni.

Quindi qual è la differenza tra questi metodi? C'è qualcosa che mi manca? Ho provato a fare un test per indagare le differenze di prestazioni:

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":"wittfl[email protected]","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"); 
     }); 
    }); 
    }); 
}; 

Si può provare here.

In Firefox, ottengo un output simile:

N = 100 
cursor.update - 39 milliseconds 
put - 40 milliseconds 
N = 1000 
cursor.update - 229 milliseconds 
put - 256 milliseconds 
N = 10000 
cursor.update - 2194 milliseconds 
put - 2096 milliseconds 
Done 

In sostanza alcuna differenza in termini di prestazioni. I risultati sono un po 'diverso in Chrome quando N è grande:

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 

Ma, come ho detto sopra, io non sono nemmeno sicuro se ci dovrebbe essere una differenza tra questi due metodi, perché sembra che essi devono fare esattamente la stessa cosa

risposta

3

La differenza principale tra update cursor e put è il fatto che è necessario recuperare l'elemento che si desidera aggiornare con cursor; d'altra parte quando si utilizza l'istruzione put, è sufficiente conoscere lo id dell'elemento che si sta aggiornando ed è sufficiente eseguire la funzione put definita al livello store. Tuttavia, questa accelerazione funzionerà solo nei casi in cui l'oggetto completo è archiviato in memoria.

Ho aggiornato il codice di un po 'ed ha ottenuto la velocità di fino:

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":"[email protected]","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++) { 
 
      //you don't need the element just update 
 
     store.put({"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":"[email protected]","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() { 
 
     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"); 
 
     }); 
 
    }); 
 
    }); 
 
};

Qui sono i miei risultati:

N = 100 
cursor.update - 46 milliseconds 
put - 28 milliseconds 
N = 1000 
cursor.update - 157 milliseconds 
put - 114 milliseconds 
N = 10000 
cursor.update - 5530 milliseconds 
put - 2391 milliseconds 
Done 
2

Sì, sono gli stessi, nel senso che entrambi utilizzano per aggiornare un valore del record. Usa semplice put se conosci già la chiave e il valore, altrimenti l'aggiornamento del cursore un po 'contorto è solo un'opzione.

Le prestazioni devono essere le stesse per l'aggiornamento di un record.

Problemi correlati