Javascript设置与阵列性能 [英] Javascript Set vs. Array performance

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

问题描述

这可能是因为集合对于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个元素和一个大测试,使用10万个元素。以下是结果。

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 set方法快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 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.

现在这是它变得有趣的地方。我使用用于循环和 .splice 的组合来从数组中删除一些元素并使用 for .delete 从集合中删除一些元素。对于小测试,从集合中删除项目的速度提高了大约三倍(2.6毫秒vs 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天全站免登陆