为什么排序javascript字符串比数字更快?

时间:2017-06-29 10:56:04

标签: javascript arrays performance sorting primitive

我正在研究一个先入为主的观点,即在javascript中排序字符串比排序整数要慢。这是基于我读过(现在找不到)的东西,这似乎是错误的,它表示javascript将字符串存储为Array<Array<int>>而不仅仅是Array<int>MDN documentation似乎与此相矛盾:

  

JavaScript的String类型用于表示文本数据。它是一组16位无符号整数值的“元素”。 String中的每个元素都占据String中的一个位置。第一个元素位于索引0,下一个元素位于索引1,依此类推。 String的长度是其中元素的数量。

如果我们将元素(数字或字符串)的“大小”定义为其文本表示的长度(对于数字元素或字符串元素,则为size = String(x).length),那么对于大量元素相同大小(一个数字,一个字符串),我期望字符串的排序等于或稍慢比排序数组,但当我运行一个简单的测试(下面的代码) ),事实证明,字符串的排序速度是排序的两倍。

我想知道字符串和数字是什么,以及javascript如何进行排序,这使得字符串排序比数字排序更快。也许我有一些误解。

结果:

~/sandbox > node strings-vs-ints.js 10000 16
Sorting 10000 numbers of magnitude 10^16
Sorting 10000 strings of length 16
Numbers: 18
Strings: 9
~/sandbox > node strings-vs-ints.js 1000000 16
Sorting 1000000 numbers of magnitude 10^16
Sorting 1000000 strings of length 16
Numbers: 3418
Strings: 1529
~/sandbox > node strings-vs-ints.js 1000000 32
Sorting 1000000 numbers of magnitude 10^32
Sorting 1000000 strings of length 32
Numbers: 3634
Strings: 1474

来源:

"use strict";
const CHARSET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghjijklmnopqrstuvwxyz0123456789:.";

function generateString(L) {
    const chars = [];
    while(chars.length < L) {
        chars.push(CHARSET[Math.floor(Math.random() * CHARSET.length)]);
    }
    return chars.join("");
}

function generateNumber(L) {
    return Math.floor(Math.random() * Math.pow(10, (L - 1))) + Math.pow(10, L - 1);
}

function generateList(generator, L, N) {
    const elements = [];
    while(elements.length < N) {
        elements.push(generator.call(null, L));
    }
    return elements;
}

function now() {
    return Date.now();
}

function getTime(baseTime) {
    return now() - baseTime;
}

function main(count, size) {
    console.log(`Sorting ${count} numbers of magnitude 10^${size}`);
    const numbers = generateList(generateNumber, size, count);
    const numBaseTime = now();
    numbers.sort();
    const numTime = getTime(numBaseTime);

    console.log(`Sorting ${count} strings of length ${size}`);
    const strings = generateList(generateString, size, count);
    const strBaseTime = now();
    strings.sort();
    const strTime = getTime(strBaseTime);

    console.log(`Numbers: ${numTime}\nStrings: ${strTime}`);
}

main(process.argv[2], process.argv[3]);

1 个答案:

答案 0 :(得分:4)

  

我正在调查一个偏见,我认为在javascript中排序字符串会比排序整数慢。

这是真的,字符串比较比数字比较更昂贵。

  

这是基于我读到的内容,声明javascript将字符串存储为Array<Array<int>>而不仅仅是Array<int>。 MDN文档似乎与此相矛盾。

是的,你读到的内容似乎确实是错误的。字符串只是字符序列(每个字符是16位值),因此它们通常存储为整数数组,或者更确切地说pointers to them。您的字符串数组确实可以被视为数组的数组。

  

当我进行一个简单的测试时,结果证明字符串的排序速度是排序的两倍。

您的代码的问题在于您将数字排序为字符串,将每个数字转换为字符串然后进行比较。见How to sort an array of integers correctly。当你解决这个问题时,请注意对比较函数的调用仍然会对内置字符串比较产生相当大的开销,所以如果你真的对关系运算符进行了基准测试(<==,{{1} })对于不同的类型,我希望数字表现得更好。