Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6992335

Asymmetric performance of BigInteger.multiply

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P4 P4
    • 8
    • 6u22
    • core-libs

      FULL PRODUCT VERSION :
      java version "1.6.0_21"
      Java(TM) SE Runtime Environment (build 1.6.0_21-b06)
      Java HotSpot(TM) Server VM (build 17.0-b16, mixed mode)


      A DESCRIPTION OF THE PROBLEM :
      The method "multiply" in class java.math.BigInteger is twice as slow as it needs to be when called on a large number with a smaller number as a parameter.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Run supplied code
      2. Observe different performance characteristics for the two different methods

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Performance characteristics should be the same in both cases.
      ACTUAL -
      One method is twice as slow as the other.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.math.BigInteger;

      public class Factorial
      {
          public static BigInteger fact1 (BigInteger n)
          {
              BigInteger n0 = n;
              BigInteger f = BigInteger.ONE;
              while (n0.compareTo (BigInteger.ZERO) > 0)
              {
                  f = n0.multiply (f);
                  n0 = n0.subtract (BigInteger.ONE);
              }

              return f;
          }

          public static BigInteger fact2 (BigInteger n)
          {
              BigInteger n0 = n;
              BigInteger f = BigInteger.ONE;
              while (n0.compareTo (BigInteger.ZERO) > 0)
              {
                  f = f.multiply (n0);
                  n0 = n0.subtract (BigInteger.ONE);
              }

              return f;
          }

          public static void main (String[] args)
          {
              BigInteger n = BigInteger.valueOf (5000);
              System.out.println ("Doing factorial for " + n);
              long t0 = System.currentTimeMillis ();
              fact1 (n);
              long t1 = System.currentTimeMillis ();
              fact2 (n);
              long t2 = System.currentTimeMillis ();
              System.out.println ("Method 1 took " + (t1 - t0) + "ms");
              System.out.println ("Method 2 took " + (t2 - t1) + "ms");
          }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Where performance is critical, add a check on the magnitude of the numbers before multiplying.

            bpb Brian Burkhalter
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: