Javascript 集与数组性能 [英] Javascript Set vs. Array performance

查看:25
本文介绍了Javascript 集与数组性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这可能是因为 Sets 对 Javascript 来说相对较新,但我一直没能在 StackO 或其他任何地方找到一篇文章来讨论两者在 Javascript 中的性能差异.那么,就性能而言,两者之间有什么区别?具体来说,当涉及到删除、添加和迭代时.

It maybe because Sets are relatively new to Javascript but I haven't been able to find an article, on StackO or anywhere else, that talks about the performance difference between the two in Javascript. So, what is the difference, in terms of performance, between the two? Specifically, when it comes to removing, adding and iterating.

推荐答案

好的,我已经测试了从数组和集合中添加、迭代和删除元素.我使用 10 000 个元素进行了小"测试,并使用 100 000 个元素进行了大"测试.这是结果.

Ok, I have tested adding, iterating and removing elements from both an array and a set. I ran a "small" test, using 10 000 elements and a "big" test, using 100 000 elements. Here are the results.

无论添加多少元素,.push 数组方法似乎比 .add 设置方法快 4 倍左右.

It would seem that the .push array method is about 4 times faster than the .add set method, no matter the number of elements being added.

在这部分测试中,我使用了 for 循环来迭代数组,使用 for of 循环来迭代集合.同样,对数组的迭代速度更快.这一次似乎是指数级的,因为在小"测试中花费了两倍的时间,在大"测试中花费的时间几乎是四倍.

For this part of the test I used a for loop to iterate over the array and a for of loop to iterate over the set. Again, iterating over the array was faster. This time it would seem that it is exponentially so as it took twice as long during the "small" tests and almost four times longer during the "big" tests.

现在这就是有趣的地方.我使用了 for 循环和 .splice 的组合从数组中删除了一些元素,我使用了 for of.delete 从集合中删除一些元素.对于小"测试,从集合中删除项目的速度大约快三倍(2.6 毫秒与 7.1 毫秒),但大"测试的情况发生了巨大变化,从数组中删除项目需要 1955.1 毫秒,而它只需要从集合中删除它们需要 83.6 毫秒,快 23 倍.

Now this is where it gets interesting. I used a combination of a for loop and .splice to remove some elements from the array and I used for of and .delete to remove some elements from the set. For the "small" tests, it was about three times faster to remove items from the set (2.6 ms vs 7.1 ms) but things changed drastically for the "big" test where it took 1955.1 ms to remove items from the array while it only took 83.6 ms to remove them from the set, 23 times faster.

在 10k 个元素时,两个测试的运行时间相当(数组:16.6 毫秒,集合:20.7 毫秒)但在处理 100k 个元素时,集合显然是赢家(数组:1974.8 毫秒,集合:83.6 毫秒),但这仅仅是因为的删除操作.否则阵列更快.我说不出为什么会这样.

At 10k elements, both tests ran comparable times (array: 16.6 ms, set: 20.7 ms) but when dealing with 100k elements, the set was the clear winner (array: 1974.8 ms, set: 83.6 ms) but only because of the removing operation. Otherwise the array was faster. I couldn't say exactly why that is.

我尝试了一些混合场景,其中创建并填充了一个数组,然后将其转换为一个集合,其中一些元素将被删除,然后该集合将重新转换为一个数组.尽管这样做会比删除数组中的元素提供更好的性能,但在集合之间进行传输所需的额外处理时间超过了填充数组而不是集合的收益.最后,只处理一个集合会更快.尽管如此,这是一个有趣的想法,如果人们选择使用数组作为一些没有重复项的大数据的数据集合,那么如果需要在一个元素中删除许多元素,那么在性能方面这可能是有利的操作,将数组转换为集合,执行移除操作,然后将集合转换回数组.

I played around with some hybrid scenarios where an array was created and populated and then converted into a set where some elements would be removed, the set would then be reconverted into an array. Although doing this will give much better performance than removing elements in the array, the additional processing time needed to transfer to and from a set outweighs the gains of populating an array instead of a set. In the end, it is faster to only deal with a set. Still, it is an interesting idea, that if one chooses to use an array as a data collection for some big data that doesn't have duplicates, it could be advantageous performance wise, if there is ever a need to remove many elements in one operation, to convert the array to a set, perform the removal operation, and convert the set back to an array.

数组代码:

var timer = function(name) {
  var start = new Date();
  return {
    stop: function() {
      var end = new Date();
      var time = end.getTime() - start.getTime();
      console.log('Timer:', name, 'finished in', time, 'ms');
    }
  }
};

var getRandom = function(min, max) {
  return Math.random() * (max - min) + min;
};

var lastNames = ['SMITH', 'JOHNSON', 'WILLIAMS', 'JONES', 'BROWN', 'DAVIS', 'MILLER', 'WILSON', 'MOORE', 'TAYLOR', 'ANDERSON', 'THOMAS'];

var genLastName = function() {
  var index = Math.round(getRandom(0, lastNames.length - 1));
  return lastNames[index];
};

var sex = ["Male", "Female"];

var genSex = function() {
  var index = Math.round(getRandom(0, sex.length - 1));
  return sex[index];
};

var Person = function() {
  this.name = genLastName();
  this.age = Math.round(getRandom(0, 100))
  this.sex = "Male"
};

var genPersons = function() {
  for (var i = 0; i < 100000; i++)
    personArray.push(new Person());
};

var changeSex = function() {
  for (var i = 0; i < personArray.length; i++) {
    personArray[i].sex = genSex();
  }
};

var deleteMale = function() {
  for (var i = 0; i < personArray.length; i++) {
    if (personArray[i].sex === "Male") {
      personArray.splice(i, 1)
      i--
    }
  }
};

var t = timer("Array");

var personArray = [];

genPersons();

changeSex();

deleteMale();

t.stop();

console.log("Done! There are " + personArray.length + " persons.")

设置代码:

var timer = function(name) {
    var start = new Date();
    return {
        stop: function() {
            var end  = new Date();
            var time = end.getTime() - start.getTime();
            console.log('Timer:', name, 'finished in', time, 'ms');
        }
    }
};

var getRandom = function (min, max) {
  return Math.random() * (max - min) + min;
};

var lastNames = ['SMITH','JOHNSON','WILLIAMS','JONES','BROWN','DAVIS','MILLER','WILSON','MOORE','TAYLOR','ANDERSON','THOMAS'];

var genLastName = function() {
    var index = Math.round(getRandom(0, lastNames.length - 1));
    return lastNames[index];
};

var sex = ["Male", "Female"];

var genSex = function() {
    var index = Math.round(getRandom(0, sex.length - 1));
    return sex[index];
};

var Person = function() {
	this.name = genLastName();
	this.age = Math.round(getRandom(0,100))
	this.sex = "Male"
};

var genPersons = function() {
for (var i = 0; i < 100000; i++)
	personSet.add(new Person());
};

var changeSex = function() {
	for (var key of personSet) {
		key.sex = genSex();
	}
};

var deleteMale = function() {
	for (var key of personSet) {
		if (key.sex === "Male") {
			personSet.delete(key)
		}
	}
};

var t = timer("Set");

var personSet = new Set();

genPersons();

changeSex();

deleteMale();

t.stop();

console.log("Done! There are " + personSet.size + " persons.")

这篇关于Javascript 集与数组性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆