Prime number calculation fun

前端 未结 18 1758
深忆病人
深忆病人 2020-12-05 15:32

We\'re having a bit of fun here at work. It all started with one of the guys setting up a Hackintosh and we were wondering whether it was faster than a Windows Box of (nearl

18条回答
  •  失恋的感觉
    2020-12-05 15:42

    My take at optimization, avoiding too cryptic tricks. I use the trick given by I-GIVE-TERRIBLE-ADVICE, which I knew and forgot... :-)

    public class Primes
    {
      // Original code
      public static void first()
      {
        int topPrime = 150003;
        int current = 2;
        int count = 0;
        int lastPrime = 2;
    
        long start = System.currentTimeMillis();
    
        while (count < topPrime) {
    
          boolean prime = true;
    
          int top = (int)Math.sqrt(current) + 1;
    
          for (int i = 2; i < top; i++) {
            if (current % i == 0) {
              prime = false;
              break;
            }
          }
    
          if (prime) {
            count++;
            lastPrime = current;
    //      System.out.print(lastPrime + " "); // Checking algo is correct...
          }
          if (current == 2) {
            current++;
          } else {
            current = current + 2;
          }
        }
    
        System.out.println("\n-- First");
        System.out.println("Last prime = " + lastPrime);
        System.out.println("Total time = " + (double)(System.currentTimeMillis() - start) / 1000);
      }
    
      // My attempt
      public static void second()
      {
        final int wantedPrimeNb = 150000;
        int count = 0;
    
        int currentNumber = 1;
        int increment = 4;
        int lastPrime = 0;
    
        long start = System.currentTimeMillis();
    
    NEXT_TESTING_NUMBER:
        while (count < wantedPrimeNb)
        {
          currentNumber += increment;
          increment = 6 - increment;
          if (currentNumber % 2 == 0) // Even number
            continue;
          if (currentNumber % 3 == 0) // Multiple of three
            continue;
    
          int top = (int) Math.sqrt(currentNumber) + 1;
          int testingNumber = 5;
          int testIncrement = 2;
          do
          {
            if (currentNumber % testingNumber == 0)
            {
              continue NEXT_TESTING_NUMBER;
            }
            testingNumber += testIncrement;
            testIncrement = 6 - testIncrement;
          } while (testingNumber < top);
          // If we got there, we have a prime
          count++;
          lastPrime = currentNumber;
    //      System.out.print(lastPrime + " "); // Checking algo is correct...
        }
    
        System.out.println("\n-- Second");
        System.out.println("Last prime = " + lastPrime);
        System.out.println("Total time = " + (double) (System.currentTimeMillis() - start) / 1000);
      }
    
      public static void main(String[] args)
      {
        first();
        second();
      }
    }
    

    Yes, I used a labeled continue, first time I try them in Java...
    I know I skip computation of the first few primes, but they are well known, no point to recompute them. :-) I can hard-code their output if needed! Beside, it doesn't give a decisive edge anyway.

    Results:

    -- First
    Last prime = 2015201
    Total time = 4.281

    -- Second
    Last prime = 2015201
    Total time = 0.953

    Not bad. Might be improved a bit, I suppose, but too much optimization can kill good code.

提交回复
热议问题