JavaScript中是否有更快的反转字符串算法?

4

我正在寻找最快的逆转字符串函数。

以下是我找到的所有互联网上的函数及其性能测试:

https://jsperf.com/javascript-reversing-string-performance

看起来最快的一个(在我看来也是最美观的)是这个:

function reverseString(str) {
  return str.split().reverse().join("");
}

也许有更高效、更快速的方法来完成这件事吗?

编写一个 C 或 WebAssembly 的绑定。 - Jonas Wilms
1
看起来似乎是这样,但是根据我的经验和写作风格,这却是其中最慢的一个。 - Bekim Bacaj
6个回答

6
这个似乎更快:
function reverseString(str) {
  let reversed = "";
  const l = str.length;
  for(let i = l-1; i >= 0; i--) {
    reversed = `${reversed}${str[i]}`;
  }
  return reversed;
}

5

在JavaScript中,除了内置的reverse函数,可能有数十种不同的方法来解决字符串反转问题。以下是我认为最有趣的三种解决方案。

解决方案1

function reverseString (str) {
  return str.split('').reverse().join('')
}

console.time("function test");
reverseString('Hello') // => 0.250ms
console.timeEnd("function test");

解决方案2
function reverseString (str) {
  let reversed = '';
  for (const character of str) {
    reversed = character + reversed
  }
  return reversed
}
console.time("function test");
reverseString('Hello') // => 0.166ms
console.timeEnd("function test");

解决方案3
function reverseString (str) {
  return str.split('').reduce((reversed, character) => character + reversed, '')
}
console.time("function test");
reverseString('Hello') // => 0.133ms
console.timeEnd("function test");

在ES6中,您有更多的选择。
function reverseString (str) {
  return [...str].reverse().join('')
}

你的第三个解决方案看起来比第一个快,谢谢! - Konrad Błachowicz
2
别指望这个!这些结果仅针对一个测试和一个单词。而且你不知道他/她的处理器当时在做什么。说真的,我甚至无法理解为什么接受这个答案,因为它根本不能开始回答OP的问题:在理论上哪种方式更快,而不是用这样糟糕的测试经验性地回答。 - Tal Kohavy

3
基于davaakhuu-erdenekhuu的解决方案,我创建了一个基准测试,以便您可以测试哪个最适合您。您可以在以下链接中查看测试结果:https://jsbench.me/4bkfflcm2z
我在Macbook Pro 16上的Firefox和Chrome上运行了它。似乎第一个选项在Firefox上最快,而第三个选项在Chrome上最快。
希望您会发现这个测试对您有用。

我将Max / Norman更简单的“向后循环和连接”方法添加到其中,它比Davaakhuu答案中的任何方法都要快得多。 - Matt Fletcher
@MattFletcher 发现与“reduce”方法相比,速度慢了5%。 - undefined

1
function reverseString(str) {
    let reversed = ""
    for (let i = str.length -1; i >= 0; i--){
        reversed = reversed + str[i]
    }
    return reversed;
}

从输入字符串的末尾开始工作是最优的,特别是取决于您如何组合字符。请记住,在数组中插入(或删除)元素并将其放在开头时,所有其他元素都必须调整其索引。

0
对于任何ArrayLike类型,最快的反转方式是逻辑上的,通过将其包装成一个反转的可迭代对象:
function reverse<T>(input: ArrayLike<T>): Iterable<T> {
    return {
        [Symbol.iterator](): Iterator<T> {
            let i = input.length;
            return {
                next(): IteratorResult<T> {
                    return i
                        ? {value: input[--i], done: false}
                        : {value: undefined, done: true};
                },
            };
        },
    };
}

现在您可以反向迭代任何数组、字符串或缓冲区,而无需为反转数据进行任何额外的复制或处理:
for(const a of reverse([1, 2, 3])) {
    console.log(a); //=> 3 2 1
}

这是最快的方法,因为您不需要复制数据,也不需要进行任何处理,只需逻辑上反转即可。


0

我在Firefox和Chrome中测试了我的方法,它是这里提供的方法中最快的。我只使用简单的for循环。

function reverseString5(str) {
  let x = '';
  
  for (let i = str.length - 1; i >= 0; --i) {
        x += str[i];
  }
  
  return x;
}

所有测试都在这里运行


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接