String based multiply

JavaScript performance comparison

Test case created by venkatloganathan

Preparation code


      
      <script>
Benchmark.prototype.setup = function() {
  const MULTIPLIER_FACTOR_CORRECTION =100;
  const SUFFIX_ZERO_01     = '0';
  const SUFFIX_ZERO_02     = '00';
  const SUFFIX_ZERO_03     = '000';
  const SUFFIX_ZERO_04     = '0000';
  const SUFFIX_ZERO_05     = '00000';
  const SUFFIX_ZERO_06     = '000000';
  const SUFFIX_ZERO_07     = '0000000';
  const SUFFIX_ZERO_08     = '00000000';
  const SUFFIX_ZERO_09     = '000000000';
  const SUFFIX_ZERO_10     = '0000000000';
  const SUFFIX_ZERO_11     = '00000000000';
  const SUFFIX_ZERO_12     = '000000000000';
  const SUFFIX_ZERO_13     = '0000000000000';
  const SUFFIX_ZERO_14     = '00000000000000';
  const SUFFIX_ZERO_15     = '000000000000000';
  const SUFFIX_ZERO_16     = '0000000000000000';
  const SUFFIX_ZERO_17     = '00000000000000000';
  const SUFFIX_ZERO_18     = '000000000000000000';
  const SUFFIX_ZERO_19     = '0000000000000000000';
  const SUFFIX_ZERO_20     = '00000000000000000000';
  
  function naturalMultiply(operand1, naturalLogDecimals)
    {
     const isOperandNegative = operand1 < 0;
      let useNegative = isOperandNegative;
  
      if (naturalLogDecimals < 0)
      {
        useNegative = !useNegative;
        naturalLogDecimals *= -1;
      }
  
      const operandAsString = operand1.toString();
  
      let operand = isOperandNegative ? operandAsString.substr(1) : operandAsString;
  
      const decimalPosition = operand.indexOf('.');
      const operandLength = operand.length;
      let result = '';
      let decimalsLength = 0;
      if (decimalPosition > 0)
      {
        result = operand.substr(0, decimalPosition);
        decimalsLength = operandLength - decimalPosition - 1;
        result += operand.substr(decimalPosition + 1, naturalLogDecimals);
      }
      else
      {
        result = operand.substr(0);
      }
  
      const excessDigits = decimalsLength - naturalLogDecimals;
      if (excessDigits > 0)
      {
        result += DECIMAL_NOTATION;
        let decimalIndex = decimalPosition + 1 + naturalLogDecimals;
        result += operand.substr(decimalIndex);
      }
      else if (excessDigits < 0)
      {
        let excess = Math.abs(excessDigits);
        switch (excess)
        {
          case 1:
            result += SUFFIX_ZERO_01;
            break;
          case 2:
            result += SUFFIX_ZERO_02;
            break;
          case 3:
            result += SUFFIX_ZERO_03;
            break;
          case 4:
            result += SUFFIX_ZERO_04;
            break;
          case 5:
            result += SUFFIX_ZERO_05;
            break;
          case 6:
            result += SUFFIX_ZERO_06;
            break;
          case 7:
            result += SUFFIX_ZERO_07;
            break;
          case 8:
            result += SUFFIX_ZERO_08;
            break;
          case 9:
            result += SUFFIX_ZERO_09;
            break;
          case 10:
            result += SUFFIX_ZERO_10;
            break;
          case 11:
            result += SUFFIX_ZERO_11;
            break;
          case 12:
            result += SUFFIX_ZERO_12;
            break;
          case 13:
            result += SUFFIX_ZERO_13;
            break;
          case 14:
            result += SUFFIX_ZERO_14;
            break;
          case 15:
            result += SUFFIX_ZERO_15;
            break;
          case 16:
            result += SUFFIX_ZERO_16;
            break;
          case 17:
            result += SUFFIX_ZERO_17;
            break;
          case 18:
            result += SUFFIX_ZERO_18;
            break;
          case 19:
            result += SUFFIX_ZERO_19;
            break;
          case 20:
            result += SUFFIX_ZERO_20;
            break;
        }
      }
      if (useNegative)
      {
        result = '-' + result;
      }
      return Number(result);  }
  
  function getExcessDigits(excessDigits) {
  let result = '';
        const excess = Math.abs(excessDigits);
  switch(excess) {
    case 1:
  result = SUFFIX_ZERO_1;
  break;
  case 2:
  result = SUFFIX_ZERO_2;
  break;
  case 3:
  result = SUFFIX_ZERO_3;
  break;
  case 4:
  result = SUFFIX_ZERO_4;
  break;
  case 5:
  result = SUFFIX_ZERO_5;
  break;
  case 6:
  result = SUFFIX_ZERO_6;
  break;
  case 7:
  result = SUFFIX_ZERO_7;
  break;
  case 8:
  result = SUFFIX_ZERO_8;
  break
  case 9:
  result = SUFFIX_ZERO_9;
  break;
  case 10:
  result = SUFFIX_ZERO_10;
  break;
  case 11:
  result = SUFFIX_ZERO_11;
  break;
  case 12:
  result = SUFFIX_ZERO_12;
  break;
  case 13:
  result = SUFFIX_ZERO_13;
  break;
  case 14:
  result = SUFFIX_ZERO_14;
  break;
  case 15:
  result = SUFFIX_ZERO_15;
  break;
  case 16:
  result = SUFFIX_ZERO_16;
  break;
  case 17:
  result = SUFFIX_ZERO_17;
  break;
  case 18:
  result = SUFFIX_ZERO_18;
  break;
  case 19:
  result = SUFFIX_ZERO_19;
  break;
  case 20:
  result = SUFFIX_ZERO_20;
  break;
  }
  return result;
  }
  
    function multiply(num1, num2)
    {
      var factor1 = multiplier(num1) * MULTIPLIER_FACTOR_CORRECTION;
      var factor2 = multiplier(num2) * MULTIPLIER_FACTOR_CORRECTION;
      var multiplier1 = num1 < 0 ? -1 : 1;
      var multiplier2 = num2 < 0 ? -1 : 1;
  
      return (Math.round(Math.abs(num1) * factor1) * Math.round(Math.abs(num2) * factor2) * multiplier1 * multiplier2) / (factor1 * factor2);
    }
    function multiplier(x)
    {
      if (x === undefined || x === null)
      {
        return NaN;
      }
  
      return Math.pow(10, decimalPoints(x));
    }
  
    function decimalPoints(num)
    {
      var numString = String(num);
  
      if (numString.indexOf('e') !== -1)
      {
        var match = numString.match(/([\d.]+)e(-?\+?)(\d+)/);
  
        if (match)
        {
          var decimalPlaces = decimalPoints(match[1]) - (match[2] === '+' ? match[3] : -match[3]);
  
          return decimalPlaces < 0 ? 0 : decimalPlaces;
        }
  
        return 0;
      }
  
      var i = numString.indexOf('.');
  
      if (i === -1)
      {
        return 0;
      }
  
      return numString.length - i - 1;
    }
  
  
  

};
</script>

Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in CCBot 2.0.0 / Other 0.0.0
Test Ops/sec
String based
for(let i = 2; i <= 9; i++) {
naturalMultiply(i, Math.pow(10, i));
}

//naturalMultiply(2, 100);
//naturalMultiply(3, 1000);
//naturalMultiply(4, 10000);
//naturalMultiply(5, 100000);

//naturalMultiply(223.34333, 100);
pending…
Old one
for(let i = 2; i <= 9; i++) {
multiply(i, Math.pow(10, i));
}

//multiply(2, 100);
//multiply(3, 1000);
//multiply(4, 10000);
//multiply(5, 100000);

//multiply(223.34333, 100);
pending…

You can edit these tests or add even more tests to this page by appending /edit to the URL.

Compare results of other browsers

0 Comments