-
-
Save puf/05cae4c18bb0f031e16d9bc46ed9748a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// This script compares the performance of three common ways to perform | |
// bulk write operations on Firestore. | |
// | |
// In test run of this script, it took: | |
// | |
// 1. `~105.4s` when using sequential individual write operations | |
// 2. `~ 2.8s` when using sequential batched write operations | |
// 3. `~ 1.5s` when using parallel individual write operations | |
// 4. `~ 1.5s` when using parallel batched write operations | |
// | |
// For a full comparison, see | |
// [What is the fastest way to write a lot of documents to Firestore?](https://stackoverflow.com/q/58897274). | |
// | |
// To use this script you will need to set the `GOOGLE_APPLITION_CREDENTIALS | |
// as described in the Firebase documentation on | |
// [initializing the SDK](https://firebase.google.com/docs/admin/setup#initialize_the_sdk) | |
// | |
(async function() { | |
var admin = require('firebase-admin'); | |
admin.initializeApp({ | |
credential: admin.credential.applicationDefault() | |
}); | |
let datas = []; | |
for (let i=0; i < 1000; i++) { | |
let data = {}; | |
for (let j=0; j < 10; j++) { | |
const random = Math.random(); | |
if (random < 0.2) { | |
data["field"+j] = ""; | |
for (let k=0; k < Math.random()*10; k++) { | |
data["field"+j] += Math.random().toString(36).substring(2, 15) | |
if (Math.random() < 0.5) data["field"+j] += " "; | |
} | |
} | |
else if (random < 0.4) { | |
data["field"+j] = Math.random() | |
} | |
else if (random < 0.6) { | |
data["field"+j] = Math.round(Math.random() * 100000); | |
} | |
else if (random < 0.8) { | |
data["field"+j] = Math.random() < 0.5; | |
} | |
else if (random < 0.9) { | |
data["field"+j] = new Date(Math.random() * Date.now()); | |
} | |
else { | |
data["field"+j] = admin.firestore.FieldValue.serverTimestamp() | |
} | |
} | |
datas.push(data); | |
} | |
//console.log(datas); | |
let collection = admin.firestore().collection("58891568"); | |
console.log(`Testing performance of writing ${datas.length} documents...`) | |
console.log(`There are now ${await getDocumentCount()} documents...\n`) | |
let timstamp; | |
timestamp = Date.now(); | |
await testSequentialIndividualWrites(JSON.parse(JSON.stringify(datas))); | |
console.log(`sequential writes took ${Date.now() - timestamp} ms`); | |
console.log(`There are now ${await getDocumentCount()} documents...\n`) | |
timestamp = Date.now(); | |
await testBatchedWrites(JSON.parse(JSON.stringify(datas))); | |
console.log(`Batched writes took ${Date.now() - timestamp} ms`); | |
console.log(`There are now ${await getDocumentCount()} documents...\n`) | |
timestamp = Date.now(); | |
await testParallelBatchedWrites(JSON.parse(JSON.stringify(datas))); | |
console.log(`Parallel batched writes took ${Date.now() - timestamp} ms`); | |
console.log(`There are now ${await getDocumentCount()} documents...\n`) | |
timestamp = Date.now(); | |
await testParallelIndividualWrites(JSON.parse(JSON.stringify(datas))); | |
console.log(`Parallel writes took ${Date.now() - timestamp} ms`); | |
console.log(`There are now ${await getDocumentCount()} documents...\n`) | |
async function testSequentialIndividualWrites(datas) { | |
while (datas.length) { | |
await collection.add(datas.shift()); | |
} | |
} | |
async function testBatchedWrites(datas) { | |
let batch = admin.firestore().batch(); | |
let count = 0; | |
while (datas.length) { | |
batch.set(collection.doc(Math.random().toString(36).substring(2, 15)), datas.shift()); | |
if (++count >= 500 || !datas.length) { | |
await batch.commit(); | |
batch = admin.firestore().batch(); | |
count = 0; | |
} | |
} | |
} | |
async function testParallelIndividualWrites(datas) { | |
await Promise.all(datas.map((data) => collection.add(data))); | |
} | |
async function testParallelBatchedWrites(datas) { | |
let batches = []; | |
let batch = admin.firestore().batch(); | |
let count = 0; | |
while (datas.length) { | |
batch.set(collection.doc(Math.random().toString(36).substring(2, 15)), datas.shift()); | |
if (++count >= 500 || !datas.length) { | |
batches.push(batch.commit()); | |
batch = admin.firestore().batch(); | |
count = 0; | |
} | |
} | |
await Promise.all(batches); | |
} | |
async function getDocumentCount() { | |
return (await collection.get()).size; | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment