Forum Discussion

BenoitB's avatar
BenoitB
Community Hero
4 years ago

replace or aqString.Replace ? Beware of speed

Needed to work on address normalization so used aqString.Replace ..

Works fine but tooooo slow ..

 

Done a little test and found that aqString.Replace is awfully slow ... really ..

 

 

 

// Slow
function cmpString(input, target) {
  if ((input == "") || (target == ""))
    return false;
  input = aqString.Replace(input, "-", " ");
  input = aqString.Replace(input, 'À', 'A');
  input = aqString.Replace(input, 'Â', 'A');
  input = aqString.Replace(input, 'Ç', 'C');
  input = aqString.Replace(input, 'È', 'E');
  input = aqString.Replace(input, 'É', 'E');
  input = aqString.Replace(input, 'Ê', 'E');
  input = aqString.Replace(input, 'Ë', 'E');
  input = aqString.Replace(input, 'Ô', 'O');
  input = aqString.Replace(input, 'Ö', 'O');
  input = aqString.Replace(input, 'Û', 'U');
  target = aqString.Replace(target, "-", " ");
  target = aqString.Replace(target, 'À', 'A');
  target = aqString.Replace(target, 'Â', 'A');
  target = aqString.Replace(target, 'Ç', 'C');
  target = aqString.Replace(target, 'È', 'E');
  target = aqString.Replace(target, 'É', 'E');
  target = aqString.Replace(target, 'Ê', 'E');
  target = aqString.Replace(target, 'Ë', 'E');
  target = aqString.Replace(target, 'Ô', 'O');
  target = aqString.Replace(target, 'Ö', 'O');
  target = aqString.Replace(target, 'Û', 'U');
  return input == target;
}

// Faster
function cmpString2(input, target) {
  if ((input == "") || (target == ""))
    return false;
  input = input.replace(/-/g, " ");
  input = input.replace(/À/g, 'A');
  input = input.replace(/Â/g, 'A');
  input = input.replace(/Ç/g, 'C');
  input = input.replace(/È/g, 'E');
  input = input.replace(/É/g, 'E');
  input = input.replace(/Ê/g, 'E');
  input = input.replace(/Ë/g, 'E');
  input = input.replace(/Ô/g, 'O');
  input = input.replace(/Ö/g, 'O');
  input = input.replace(/Û/g, 'U');
  target = target.replace(/-/g, " ");
  target = target.replace(/À/g, 'A');
  target = target.replace(/Â/g, 'A');
  target = target.replace(/Ç/g, 'C');
  target = target.replace(/È/g, 'E');
  target = target.replace(/É/g, 'E');
  target = target.replace(/Ê/g, 'E');
  target = target.replace(/Ë/g, 'E');
  target = target.replace(/Ô/g, 'O');
  target = target.replace(/Ö/g, 'O');
  target = target.replace(/Û/g, 'U');
  return input == target;
}

// The fastest
function cmpString3(input, target) {
  const chars = {'-' : ' ', 'À' : 'A', 'Â': 'A', 'Ç': 'C', 'È': 'E', 'É': 'E', 'Ê': 'E', 'Ë': 'E', 'Ô': 'O', 'Ö': 'O', 'Û': 'U'};
  input  = input.replace(/[-ÀÂÇÈÉÊËÔÖÛ]/g, m => chars[m]);
  target = target.replace(/[-ÀÂÇÈÉÊËÔÖÛ]/g, m => chars[m]);
  return input == target; 
}  

function testit() {
var a = "ÉTANG-SALÉ";
var b = "ETANG SALE";

Log.Message('1 >');
for (let i = 0; i < 100; i ++)
  cmpString(a,b);
Log.Message('Fin 1');

Log.Message('2 >');
for (let i = 0; i < 10000000; i ++)
  cmpString2(a,b);
Log.Message('Fin 2');
Log.Message('3 >');
for (let i = 0; i < 1000000; i ++)
  cmpString3(a,b);
Log.Message('Fin 3');

Log.Message(cmpString(a,b));
Log.Message(cmpString2(a,b));
Log.Message(cmpString3(a,b));
}

 

 

 

100 iterations of the method with aqString.Replace => 6 seconds ...

10000000 iterations of the method with replace simple => 59 seconds ..

10000000 iterations of the method with optimized replace => 14 seconds ..

 

The main advantage of aqString.Replace() is the simple way to manage case. Unless that the native string replace is so faster ...

 

By the way the localeCompare which is the best to fast compare with accents and diacritics doesnt use the options e.g. {sensitivity:variant} so it's totally useless. It's due to TestComplete 😞

 

2 Replies

  • sonya_m's avatar
    sonya_m
    SmartBear Alumni (Retired)

    100 iterations of aqString.Replace => 6 seconds 

    😮 It is slow!

    • BenoitB's avatar
      BenoitB
      Community Hero

      In fact, 100 itérations of the method which has 22 aqString.replace -> 2200 aqString.Replace in 6 seconds.

      Seem nice but if you compare with native replace it is slow.

      If no need of big amount of replacement, aqString.Replace is enough and convenient.

      If need of speed and large scale of data, it's not enough.

       

      On my project, needed to work on more than 1M replacements ... and target time is under the hour ...The optimized replace version was the solution.