Javascript string replace: Is it possible to use a string as the first argument (for speed), but "match globally"?

string.replace(/\./g,'_') is the behavior I would like, but I would prefer not to use the actual regular expression because of this jsperf , which shows that using a string like string.replace('.','_') much faster.

Unfortunately (and this may be disgusting for jsperf, since this in no way becomes obvious), it seems that the replacement will only work in the first match, so it will be identical only

 string.replace(/\./,'_') 

This is probably enough to invalidate the comparison, because it is only twice as fast (on Webkit) for a simple replace string, but in fact it does only 1/4 of the work, replacing only one period with a space and not all.

There is an obvious approach that

 while(string.indexOf('.') !== -1) string = string.replace('.','_'); 

but is there any better or faster way to achieve this?

+4
source share
3 answers

Well, the performance test speaks for itself . I modified the last test to make a "replacement cycle" (not against nesting a prototype, it's just a test)

 String.prototype.loopReplace = function(replacee,replacer){ var result = this; while(!!~(result = result.replace('.',' ')).indexOf('.')){} return result; } 

And among proven browsers, the pre-created RegExp wins over others for a good reason:

  • Since RegExp is always the same, caching is a good idea, not re-creating the same objects in place.

  • The indexOf is replace slow, probably due to the repeated operations of indexOf and replace . replace creates a new line every time it starts, which may be the reason.

  • split - join slow, probably because the browser must first create an array, then a string and then drop the array. Although browsers may have optimized array creation, it is still slower.

0
source

Wait a minute. It:

 string.replace( /./g, '_' ) 

does not match this:

 string.replace( '.', '_' ) 

The first replaces any character with an underscore, not just periods.

You do not mean:

 string.replace( /\./g, '_' ) 

See how this is done for performance; it may be better than wrong.

Also, do you do this a lot in a row? Is the performance different?

+1
source

Your jsperf is not a good comparison, since string.replace('.','_') Does not actually do the same job. Compare code replacing 1 . code replacing 4 . not particularly helpful. Here's a fairer comparison (and providing non-regex to replace a better chance by expanding the loop), where you see that using regex is actually faster.

0
source

Source: https://habr.com/ru/post/1479194/


All Articles