Performance of string substitution

Asked

Viewed 275 times

10

I need to do some bulk replacement operations with Javascript. For my specific problem, let’s assume that I need to replace a specific substring. I need to replace each occurrence of "blue" with "green".

So I have two ways of doing:

var foo = pegaTexto(); // imagine que isso retorna uma string qualquer;
foo = foo.replace("azul", "verde");

Or:

var foo = pegaTexto();
foo = foo.replace(new RegExp("azul"), "verde");

In my view, in such a situation, the only practical use of using a regular expression would be to specify a flag (to say for example whether the search should be global), but in my case I am omitting the flags of the expression builder.

I have one question, however, regarding the performance of these two distinct forms.

Forcing the use of regular expression has some impact on performance?

How can I measure it?

  • 1

    http://jsperf.com/teste-de-replace

  • 1

    @Sergio thank you very much! This is worth an answer, if you do, I will be happy to score and mark as correct :)

2 answers

18


You can use the jsperf.com, there it is possible to assemble tests to test different variations.

Fez a test and gave me 13~15% slower with Regexp.

The code I used:

var texto = 'amarelo verde encarnado azul branco';

// com regex    
var regex = new RegExp("azul");
for(var i = 0; i < 50000; i++){
   var resultado = texto.replace(regex, "verde");
}

// com replace de string
for(var i = 0; i < 50000; i++){
   var resultado = texto.replace("azul", "verde");
}

The quickest way for this function, however, seems to be split/Join - break the string to each word and re-join with the new word. Credit for the reply of @utluiz.

var novaString = texto.split('palavraAntiga').join('palavraNova');
  • 1

    I didn’t know the jsperf, thank you very much :) I imagine the operation with RegExp is slower due to time lost with the regular expression object construction operation.

  • @Renan, I’ve made an update: http://jsperf.com/teste-de-replace

  • In time: even though constructing the regular expression out of the loop and reusing a single object every fifty thousand times, the regular expression is still slower.

  • 1

    If you put 'new Regexp("blue")' out of the is faster, but still slower than 'replace("blue", "green")'.

  • @Sergio I added the revision in http://jsperf.com/teste-de-replace/3. Here it got 13% slower. If you can, update the response.

  • @Lucasnunes, thank you. I updated.

  • @Sergio reviewed his test by removing the internal loop: http://jsperf.com/teste-replace/5 It turns out that the loop was also being tested, in case the performance of the loop also falls in the evaluation which impairs the result, and jsperf already does a series of algorithm test repetitions, the more isolated the more accurate the result.

  • 1

    @Gabrielgartz, good! interesting to see the split/Join also in the race :)

  • I stayed surprised with the fact that the most performatic method varies so much from one browser to another!

Show 4 more comments

7

I added two more substitution techniques who do not use regular expressions at the jsperf original by Sergio.

split/Join

var resultado = texto.split('azul').join('verde');

index

var pos = texto.indexOf('azul');
var ultpos = 0;
var resultado = '';
while (pos >= 0) {
    resultado += texto.substring(ultpos, pos) + 'verde';
    ultpos = pos + 4;
    pos = texto.indexOf('azul', pos + 4);
}
if (ultpos < texto.length) {
    resultado += texto.substring(ultpos, texto.length);
}

Results

Analyzing the results in other browsers by other users, I noticed that there is no consensus on the fastest method.

See the chart when I write:

inserir a descrição da imagem aqui

In short:

  • split/join wins in Chrome
  • indexOf wins in Firefox and Opera
  • regex win in the IE :/
  • Interesting, I hadn’t thought of using split and Join this way. I’m surprised. + 1.

  • 1

    Good idea to bring the split/Join to the "race" +1!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.