Last active
November 18, 2021 16:46
-
-
Save AbdelrahmanHafez/c6780daee01600844944f10765cd0b80 to your computer and use it in GitHub Desktop.
Performance comparison between mongoose `Document#save(...)` and `Model.bulkSave(...)`
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
import mongoose from 'mongoose'; | |
const { Schema } = mongoose; | |
const ALL_BANK_ACCOUNTS_COUNT = 100_000; | |
start().catch(console.error); | |
async function start () { | |
await runExperiment(bulkSaveDocuments); | |
await runExperiment(saveDocumentsIndividually); | |
} | |
async function runExperiment (savingFunction) { | |
await prepareDatabase(); | |
const BankAccount = generateBankAccountModel(); | |
const newBankAccountsToCreate = createEmptyArrayWithLength(ALL_BANK_ACCOUNTS_COUNT / 2).map(() => { | |
return new BankAccount({ balance: generateRandomInteger(0, 100) }); | |
}); | |
const bankAccountsToUpdate = createEmptyArrayWithLength(ALL_BANK_ACCOUNTS_COUNT / 2).map(() => { | |
return new BankAccount({ balance: generateRandomInteger(0, 100) }); | |
}); | |
await BankAccount.insertMany(bankAccountsToUpdate); | |
bankAccountsToUpdate.forEach((bankAccount) => { | |
bankAccount.balance = generateRandomInteger(0, 100); | |
}); | |
const allBankAccountsDocuments = [ | |
...newBankAccountsToCreate, | |
...bankAccountsToUpdate | |
]; | |
const timestampBeforeSaving = Date.now(); | |
await savingFunction(allBankAccountsDocuments, BankAccount); | |
const timestampAfterSaving = Date.now(); | |
console.log(`Time elapsed for ${savingFunction.name} is ${timestampAfterSaving - timestampBeforeSaving}ms.`); | |
} | |
async function prepareDatabase () { | |
await mongoose.connect('mongodb://localhost:27017/test'); | |
await mongoose.connection.dropDatabase(); | |
} | |
function generateBankAccountModel () { | |
if (mongoose.models.BankAccount) { | |
return mongoose.models.BankAccount; | |
} | |
const bankAccountSchema = new Schema({ balance: Number }); | |
const BankAccount = mongoose.model('BankAccount', bankAccountSchema); | |
return BankAccount; | |
} | |
async function bulkSaveDocuments (documents, Model) { | |
await Model.bulkSave(documents); | |
} | |
async function saveDocumentsIndividually (documents) { | |
await Promise.all(documents.map(async (document) => { | |
await document.save(); | |
})); | |
} | |
function createEmptyArrayWithLength (desiredLength) { | |
const arr = Array.from({ length: desiredLength }); | |
return arr; | |
} | |
function generateRandomInteger (min, max) { | |
return Math.floor(generateRandomFloat(min, max)); | |
} | |
function generateRandomFloat (min, max) { | |
return Math.random() * (max - min) + min; | |
} |
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
Time elapsed for bulkSaveDocuments is 12141ms. | |
Time elapsed for saveDocumentsIndividually is 31323ms. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment