Skip to content

Instantly share code, notes, and snippets.

@freeeve
Created January 29, 2012 19:30
Show Gist options
  • Save freeeve/1700270 to your computer and use it in GitHub Desktop.
Save freeeve/1700270 to your computer and use it in GitHub Desktop.
ordered collection with arbitrary moves; method comparison
var populateMulti = function(colSize) {
db.test10.drop();
for(var i=0;i<colSize;i++) {
db.test10.save({name:""+i, order:i});
}
db.test10.ensureIndex({order:1});
}
var moveMulti = function(oldPos,newPos) {
if(oldPos == newPos) return;
db.test10.update({order:oldPos},
{$set:{order:newPos, hold:true}},
false, false);
if(oldPos < newPos) {
db.test10.update({order:{$gt:oldPos, $lte:newPos}, hold:{$exists:false}},
{$inc:{order:-1}},
false, true);
} else if(newPos < oldPos) {
db.test10.update({order:{$gte:newPos, $lt:oldPos}, hold:{$exists:false}},
{$inc:{order:1}},
false, true);
}
db.test10.update({order:newPos},
{$unset:{hold:1}},
false, false);
}
var benchMulti = function(colSize, iterations) {
populateMulti(colSize);
var d = new Date();
for(var i = 0; i < iterations; i++) {
var oldPos = Math.floor(Math.random()*colSize);
var newPos = Math.floor(Math.random()*colSize);
moveMulti(oldPos,newPos);
}
var tot = new Date() - d;
print("coll size: "+colSize+"; finished "+iterations+" moves with multi-update in: " + tot + "ms; "+(tot/iterations)+"ms per move");
}
var populateLinked = function(colSize) {
db.test10.drop();
db.test10.save({name: ""+0, prev:null, next:""+1});
for(var i=1;i<colSize-1;i++) {
db.test10.save({name:""+i, prev:""+(i-1), next:""+(i+1)});
}
db.test10.save({name: ""+(colSize-1), prev:""+(i-1), next:null});
db.test10.ensureIndex({name:1});
}
var moveLinked = function(oldPos,newPos) {
var toMove = db.test10.findOne({name:""+oldPos});
var dest = db.test10.findOne({name:""+newPos});
if(toMove.prev != null) {
db.test10.update({name: toMove.prev}, {$set:{next:toMove.next}}, false, false);
}
if(toMove.next != null) {
db.test10.update({name: toMove.next}, {$set:{prev:toMove.prev}}, false, false);
}
if(dest.prev != null) {
db.test10.update({name: dest.prev}, {$set:{next:toMove.name}}, false, false);
}
db.test10.update({name: toMove.name}, {$set:{prev:dest.prev, next:dest.name}}, false, false);
db.test10.update({name: dest.name}, {$set:{prev:toMove.name}}, false, false);
}
var benchLinked = function(colSize, iterations) {
populateLinked(colSize);
var d = new Date();
for(var i = 0; i < iterations; i++) {
var oldPos = Math.floor(Math.random()*colSize);
var newPos = Math.floor(Math.random()*colSize);
moveLinked(oldPos,newPos);
}
var tot = new Date() - d;
print("coll size: "+colSize+"; finished "+iterations+" moves with linked in: " + tot + "ms; "+(tot/iterations)+"ms per move");
}
var bench = function() {
var colSize = 10;
var iterations = 5000;
benchMulti(colSize, iterations);
benchLinked(colSize, iterations);
colSize = 100;
benchMulti(colSize, iterations);
benchLinked(colSize, iterations);
colSize = 500;
benchMulti(colSize, iterations);
benchLinked(colSize, iterations);
colSize = 1000;
benchMulti(colSize, iterations);
benchLinked(colSize, iterations);
colSize = 10000;
benchMulti(colSize, iterations);
benchLinked(colSize, iterations);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment