Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
node / javascript performance : Set vs Object and Map vs Object

Set vs Object

node version : v4.1.2
platform: Intel I7, 16G DDR3, Ubuntu x64

var theSet = new Set();
start = process.hrtime();
/***********************************/
for(let i = 0 ; i < N; i++ ) {
    let v = i%20;
    if (!theSet.has(v))
        theSet.add(v);
}
/***********************************/
console.log('section 1 : ' + timeUse(start));


obj = {};
start = process.hrtime();
/***********************************/
for(let i = 0 ; i < N; i++) {
    let v = i%20;
    if (!obj[v])
        obj[v] = 1;

}
/***********************************/
console.log('section 2 : ' + timeUse(start));

result :

# N = 1M
section 1 : 28348894ns
section 2 : 13017222ns

# N = 1K
section 1 : 1616666ns
section 2 : 109862ns

conclusion: If unnecessary, use Object instead of Set for performance benefit.

Map vs Object

var themap = new Map();
start = process.hrtime();
/***********************************/
for(let i = 0 ; i < N; i++ ) {
    let v = i%20;
    if (!themap.get(v))
        themap.set(v, i);
}
/***********************************/
console.log('section 1 : ' + timeUse(start));


obj = {};
start = process.hrtime();
/***********************************/
for(let i = 0 ; i < N; i++) {
    let v = i%20;
    if (!obj[v])
        obj[v] = 1;
}
/***********************************/
console.log('section 2 : ' + timeUse(start));

result:

# N = 1M
section 1 : 27290298ns
section 2 : 12362120ns

# N = 1K
section 1 : 1749059ns
section 2 : 63746ns

conclusion: same as Set vs Object

@jngbng
Copy link

jngbng commented Nov 17, 2017

The performance depends on the characteristic of the input data.
If you can expect low percentage of duplicates in your data, Set is faster.
Refer to https://github.com/jngbng/set-vs-object

Loading

@PhiLhoSoft
Copy link

PhiLhoSoft commented Jun 29, 2018

Should be interesting to redo this test with modern Node (native support of ES6), and with non-numerical keys. Most common use case for these data structures remain with string keys, if you have sequential numerical keys, you better use an array... 😄

Loading

@Alchemist0823
Copy link

Alchemist0823 commented Apr 29, 2019

What a dumb test let v = i%20.

Loading

@lostrepo
Copy link

lostrepo commented Nov 21, 2019

String key access/write speed (Edited because test had too many flaws)

TL;DR:
Objects: slowest key access, slowest key write.
Sets: fastest key access, fastest key write.
Map: fast key access, fast key write.

Results of modified test when keys are relatively long strings (1x2.6Ghz cpu, node-v12.13.0-linux-x64):

All times in nanoseconds. W - write, R - access aka 'read'.
1 Million keys processed.

MapW : 1451322615
MapR : 475388668

SetW : 1345909415
SetR : 342153791

ObjW : 4223606810
ObjR : 813454233

SetW : 1408910400
SetR : 347006460

ObjW : 4063972437
ObjR : 767037134

MapW : 1533040516
MapR : 513181434

ObjW : 3972683227
ObjR : 798928083

MapW : 1498085287
MapR : 512821606

SetW : 1549353712
SetR : 380987238

Source (formatting sucks in comments):

	// I've read long time ago that reverse while loop can help to miss cache
	// Never believed this claim but just in case it's true we will utilize it
	// @note: For test purity we must perform writes and reads in separate functions (6 total)
	// @note: For test purity we must exclude existance checks or even add test only for it (3 extra functions)
	var N	=	1000000;
	// Map => Set => Obj
	setTimeout(function(){
		mapTest(N);
		setTimeout(function(){
			setTest(N);
			setTimeout(function(){
				objTest(N);
			}, 100);
		}, 100);
	}, 16);
	
	// Set => Obj => Map
	setTimeout(function(){
		setTest(N);
		setTimeout(function(){
			objTest(N);
			setTimeout(function(){
				mapTest(N);
			}, 100);
		}, 100);
	}, 16);
	
	// Obj => Map => Set
	setTimeout(function(){
		objTest(N);
		setTimeout(function(){
			mapTest(N);
			setTimeout(function(){
				setTest(N);
			}, 100);
		}, 100);
	}, 16);
	
	
	
	
	function timeDiff(hrtime){
		var t	=	process.hrtime(hrtime);
		return t[1] + t[0] * 1000000000;
	}
	
	
	
	
	
	function mapTest(N){
		var
		themap	=	new Map(),
		tmp		=	null,
		str		=	'this/is/strange/path/name/that/never/will/be/used/231313.js?abcd=0',
		keys	=	(function(){
			var res	=	[];
			for(let i = 0 ; i < N; i++ ){
				res[i]	=	i + str;
			}
			return res;
		})(),
		v		=	null,
		i		=	0,
		start	=	0;
		
		start = process.hrtime();
		i	=	N;
		while(i--){
			v	=	keys[i];
			if (!themap.has(v))
			themap.set(v, i);
		}
		console.log('MapW : ' + timeDiff(start));
		
		start = process.hrtime();
		i	=	N;
		while(i--){
			v	=	keys[i];
			if (themap.has(v))
			tmp	=	themap.get(v, i);
		}
		console.log('MapR : ' + timeDiff(start));
		console.log('');
	}
	
	
	
	function setTest(N){
		var
		theSet	=	new Set(),
		tmp		=	null,
		str		=	'this/is/strange/path/name/that/never/will/be/used/231313.js?abcd=0',
		keys	=	(function(){
			var res	=	[];
			for(let i = 0 ; i < N; i++ ){
				res[i]	=	i + str;
			}
			return res;
		})(),
		v		=	null,
		i		=	0,
		start	=	0;
		
		start = process.hrtime();
		i	=	N;
		while(i--){
			v	=	keys[i];
			if (!theSet.has(v))
			theSet.add(v);
		}
		console.log('SetW : ' + timeDiff(start));
		
		start	=	process.hrtime();
		i	=	N;
		while(i--){
			v	=	keys[i];
			if (theSet.has(v))
			tmp	=	v;
		}
		console.log('SetR : ' + timeDiff(start));
		console.log('');
	}
	
	
	
	function objTest(N){
		var obj	=	{},
		tmp		=	null,
		str		=	'this/is/strange/path/name/that/never/will/be/used/231313.js?abcd=0',
		keys	=	(function(){
			var res	=	[];
			for(let i = 0 ; i < N; i++ ){
				res[i]	=	i + str;
			}
			return res;
		})(),
		v		=	null,
		i		=	0,
		start	=	0;
		
		start	=	process.hrtime();
		i	=	N;
		while(i--){
			v	=	keys[i];
			if (!obj.hasOwnProperty(v))
			obj[v]	=	1;
		}
		console.log('ObjW : ' + timeDiff(start));
		
		start	=	process.hrtime();
		i	=	N;
		while(i--){
			v	=	keys[i];
			if (obj.hasOwnProperty(v))
			tmp	=	obj[v];
		}
		console.log('ObjR : ' + timeDiff(start));
		console.log('');
	}

Loading

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment