Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Performance comparison between mongoose `Document#save(...)` and `Model.bulkSave(...)`
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;
}
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