为什么数字数组比对象数组排序更快,Javascript中的数据更少?

为什么数字数组比对象数组排序更快,Javascript中的数据更少?,javascript,arrays,node.js,sorting,Javascript,Arrays,Node.js,Sorting,对于node.js中的应用程序,我必须根据某个数值(即数字秩)按降序对数组元素进行排序。由于我的应用程序对性能至关重要,我决定构建我的数据结构,以便优化排序。我假设数组中每个元素包含的数据越少,排序速度就越快。为了验证我的假设,我在三个长度为10000的不同数组上运行了以下内容: 编辑:伙计们,我最初的测试似乎有缺陷。第一次测试比接下来的测试花费的时间要长得多。因此,我修改了我的测试代码,在实际排序之前有一个“缓冲区”排序。此外,我将测试顺序旋转为固定数量的试验,以减少测试顺序本身可能产生的任何

对于node.js中的应用程序,我必须根据某个数值(即数字秩)按降序对数组元素进行排序。由于我的应用程序对性能至关重要,我决定构建我的数据结构,以便优化排序。我假设数组中每个元素包含的数据越少,排序速度就越快。为了验证我的假设,我在三个长度为10000的不同数组上运行了以下内容:

编辑:伙计们,我最初的测试似乎有缺陷。第一次测试比接下来的测试花费的时间要长得多。因此,我修改了我的测试代码,在实际排序之前有一个“缓冲区”排序。此外,我将测试顺序旋转为固定数量的试验,以减少测试顺序本身可能产生的任何偏差。我已经相应地修改了结果

完整资料来源:

var缓冲区=[781197,…];
var sparseArray=[781197,…];
var sparseArray2=[{'a':781197},…];
var denseArray=[{'a':781197,'b':['r','a','n','d','o','m']},…];
/*缓冲区:由于某些原因,第一次测试总是比其他测试花费更长的时间。我添加这个是为了消除之前的偏见*/
控制台时间(“缓冲区”);
random.sort(compareSparse);
console.timeEnd('buffer');
console.log(缓冲区[0]);//打印“58”
/*sparseArray:元素为数字的数组*/
控制台。时间(“稀疏”);
sparseArray.sort(compareSparse);
console.timeEnd(“稀疏”);
console.log(sparseArray[0]);//打印“58”
/*sparseArray2(不是一个准确的名称,只是变得懒惰):
元素为具有单个键值对映射的对象的数组
将任意名称“a”改为数字(我们根据其排序)*/
控制台时间('sparse2');
sparsearray 2.排序(比较);
控制台.timeEnd('sparse2');
console.log(sparsearray 2[0]);//打印“{a:58}”
/*DenSarray:其元素为具有两个键值的对象的数组
将任意键“a”映射到一个数字(我们根据该数字进行排序)的对,以及
数组的另一个任意键“b”(该键应该是
用于我的假设的额外数据)*/
控制台。时间(“密集”);
Densarray.排序(比较);
console.timeEnd('dense');
console.log(denseArray[0]);//打印“{a:58,b:['r',a',n',d',o',m']}”
函数比较parse(a,b){
if(ab){
返回1;}
否则{
返回0;
}
}
功能比较(a、b){
如果(a.ab.a){
返回1;}
否则{
返回0;
}
}
}
旧测试:

经过25次试验(我知道,样本量很小,但我都是手动完成的),我得到了以下平均排序时间:

  • Sparsarray:(24+23+21+23+21+22+22+22+22+21+20+22+24+24+21+22+22+25+23+24+23+21+21+23)/25=22.32ms
  • Sparsarray 2:(4+4+4+4+4+5+5+5+4+6+5+5+4+5+5+5+5+4+4+5+6+4+5+4+4+4+5)/25=4.56ms
  • Densarray:(5+5+4+5+5+5+5+5+5+6+5+5+4+4+5+5+5+4+5+5+6+5+5+5+4)/25=4.88ms
新测试:

经过25次试验(我知道,样本量很小,但我都是手动完成的),我得到了以下平均排序时间:

  • sparseArray:(4+4+4+3+4+4+4+4+4+4+4+3+4+4)/15=3.867ms
  • Sparsarray 2:(4+4+4+6+5+4+4+4+5+5+4+5+5+5)/15=4.533ms
  • Densarray:(4+4+4+5+4+4+4+4+5+5+5+5)/15=4.466ms
因此,我得出以下结论:

  • 数字数组的排序速度比值为数字的对象数组快。这在直觉上是有道理的
  • 出于某种原因,自相矛盾的是,特定元素中的数据越多,排序速度就越快(如SparSearray 2与denseArray运行时所证明的)
我想知道的是:

  • 这些结论是否有我的测试以外的任何文档/其他支持?也就是说,我得出了正确的结论吗
  • 为什么?为什么数字数组比对象数组排序快(从直觉上讲是有道理的,但如果有,背后的解释是什么)?不仅如此,为什么包含更多数据的数组似乎比包含更少数据的数组排序更快
请注意,我并没有接受这些结论或任何东西。样本量很小,而且我的测试之前被证明有缺陷,所以我的结果很可能只是测试不好的结果。此外,似乎有各种因素,我没有意识到这可能会影响结果(正如Ryan O'Hara在我之前的帖子中指出的)。这篇文章的重点是发现Javascript中排序行为的任何基于事实的解释


谢谢你的阅读

我认为这与javascript中排序的工作方式有关。排序前的数字如果未提供比较函数,则操作需要一些时间

这些结论是否有任何文件/其他文件支持 我的测试?也就是说,我得出了正确的结论吗

任何规范都不要求提供如何实现
.sort()
的细节,因此
.sort()
的性能方面只能通过在感兴趣的浏览器或JS实现中对感兴趣的数据集进行性能测试来发现。几乎所有的性能问题都最好在对您重要的特定环境中进行测试。将军
var buffer = [781197, ... ];
var sparseArray = [781197, ... ];
var sparseArray2 = [{'a' : 781197}, ...];
var denseArray = [{'a' : 781197, 'b': ['r', 'a', 'n', 'd', 'o', 'm'] }, ...];

/* buffer : for some reason, the first test always takes significantly longer than the others. I've added this to try to remove whatever bias there was before... */
console.time('buffer');
random.sort(compareSparse);
console.timeEnd('buffer');
console.log(buffer[0]); // prints "58"


/* sparseArray : an array whose elements are numbers */
console.time('sparse');
sparseArray.sort(compareSparse);
console.timeEnd('sparse');
console.log(sparseArray[0]); // prints "58"

/* sparseArray2 (not an accurate name, just got lazy) :
   an array whose elements are objects with a single key-value pair mapping
   an arbitrary name 'a' to a number (which we sort on) */
console.time('sparse2');
sparseArray2.sort(compareDense);
console.timeEnd('sparse2');
console.log(sparseArray2[0]); // prints "{ a: 58 }"

/* denseArray : an array whose elements are objects with two key-value
   pairs mapping an arbitrary key 'a' to a number (which we sort on) and
   another arbitrary key 'b' to an array (which is just supposed to be 
   extra data for the purpose of my hypothesis) */
console.time('dense');
denseArray.sort(compareDense);
console.timeEnd('dense');
console.log(denseArray[0]); // prints "{ a: 58, b: [ 'r', 'a', 'n', 'd', 'o', 'm' ] }"

function compareSparse(a, b) {
    if (a < b) {
        return -1;
    } else if (a > b) {
        return 1;   }
    else {
        return 0;
    }
}

function compareDense(a, b) {
    if (a.a < b.a) {
            return -1;
        } else if (a.a > b.a) {
            return 1;   }
        else {
            return 0;
        }
    }
}