6
\$\begingroup\$

Can you give me some idea how to optimize the switch statements, maybe a for or do while loop? Which is faster, switch or for/while loop?

public class CalculateTheValueOfE {
 static long start1 = System.currentTimeMillis();
 static int numberOfThread = 4;
 private static int precision = 0;
 private static int threadCount = 0;
 private static String defaultFile = null;
 static BigDecimal result = BigDecimal.ONE;
 public static BigDecimal factorial(int x) {
 BigDecimal prod = new BigDecimal("1");
 for (int i = x; i > 1; i--) {
 prod = prod.multiply(new BigDecimal(i));
 }
 return prod;
 }
 public static Runnable getRunner(final int from, final int to) {
 Runnable runner = new Runnable() {
 @Override
 public void run() {
 BigDecimal e = BigDecimal.valueOf(0);
 for (int i = from; i < to; i++) {
 e = e.add(BigDecimal.valueOf(3 * 3 * i * i + 1).divide(factorial(3 * i), new MathContext(1000, RoundingMode.HALF_UP)));
 }
 addResult(e);
 }
 };
 return runner;
 }
 public static synchronized void addResult(BigDecimal e) {
 result = result.add(e);
 }
 public static void main(String[] args) throws InterruptedException, IOException {
 //Thread tr[] = new Thread[threadCount];
 // Runnable r[] = new Runnable[numberOfThread];
 File file = new File("result.txt");
 FileOutputStream fis = new FileOutputStream(file);
 PrintStream out = new PrintStream(fis);
 System.setOut(out);
 for (int i = 0; i < args.length; i++) {
 System.out.println(i + " " + args[i]);
 }
 threadCount = Integer.valueOf(args[1]);
 precision = Integer.valueOf(args[3]);
 defaultFile = args[5];
 System.out.println("Number of threads: " + threadCount + " precision: " + precision + " default file to save the result: " + defaultFile);
 //String numberOfThreads = args[1];
 //String precision = args[3];
 //String defaultFile = args[5];
 int calculation = precision / threadCount;
 /* for (int i = 1; i<= precision; i+=calculation){
 Runnable r = getRunner(i, calculation + 1);
 Thread t = new Thread(r);
 t.start();
 t.join();
 i=250;
 }*/
 switch (threadCount) {
 case 1:
 Runnable r1 = getRunner(1, precision);
 Thread t1 = new Thread(r1);
 t1.start();
 t1.join();
 break;
 case 2:
 r1 = getRunner(1, precision / 2 + 1);
 Runnable r2 = getRunner(precision / 2 + 1, precision);
 t1 = new Thread(r1);
 Thread t2 = new Thread(r2);
 t1.start();
 t2.start();
 t1.join();
 t2.join();
 break;
 case 3:
 r1 = getRunner(1, precision / 3 + 1);
 r2 = getRunner(precision / 3 + 1, 2 * precision / 3 + 1);
 Runnable r3 = getRunner(2 * precision / 3 + 1, precision);
 t1 = new Thread(r1);
 t2 = new Thread(r2);
 Thread t3 = new Thread(r3);
 t1.start();
 t2.start();
 t3.start();
 t1.join();
 t2.join();
 t3.join();
 break;
 case 4:
 r1 = getRunner(1, precision / 4 + 1);
 r2 = getRunner(precision / 4 + 1, 2 * precision / 4 + 1);
 r3 = getRunner(2 * precision / 4 + 1, 3 * precision / 4 + 1);
 Runnable r4 = getRunner(3 * precision / 4 + 1, precision);
 t1 = new Thread(r1);
 t2 = new Thread(r2);
 t3 = new Thread(r3);
 Thread t4 = new Thread(r4);
 t1.start();
 t2.start();
 t3.start();
 t4.start();
 t1.join();
 t2.join();
 t3.join();
 t4.join();
 break;
 case 5:
 r1 = getRunner(1, precision / 5 + 1);
 r2 = getRunner(precision / 5 + 1, 2 * precision / 5 + 1);
 r3 = getRunner(2 * precision / 5 + 1, 3 * precision / 5 + 1);
 r4 = getRunner(3 * precision / 5 + 1, 4 * precision / 5 + 1);
 Runnable r5 = getRunner(4 * precision / 5 + 1, precision);
 t1 = new Thread(r1);
 t2 = new Thread(r2);
 t3 = new Thread(r3);
 t4 = new Thread(r4);
 Thread t5 = new Thread(r5);
 t1.start();
 t2.start();
 t3.start();
 t4.start();
 t5.start();
 t1.join();
 t2.join();
 t3.join();
 t4.join();
 t5.join();
 break;
 case 6:
 r1 = getRunner(1, precision / 6 + 1);
 r2 = getRunner(precision / 6 + 1, 2 * precision / 6 + 1);
 r3 = getRunner(2 * precision / 6 + 1, 3 * precision / 6 + 1);
 r4 = getRunner(3 * precision / 6 + 1, 4 * precision / 6 + 1);
 r5 = getRunner(4 * precision / 6 + 1, 5 * precision / 6 + 1);
 Runnable r6 = getRunner(5 * precision / 6 + 1, precision);
 t1 = new Thread(r1);
 t2 = new Thread(r2);
 t3 = new Thread(r3);
 t4 = new Thread(r4);
 t5 = new Thread(r5);
 Thread t6 = new Thread(r6);
 t1.start();
 t2.start();
 t3.start();
 t4.start();
 t5.start();
 t6.start();
 t1.join();
 t2.join();
 t3.join();
 t4.join();
 t5.join();
 t6.join();
 break;
 case 7:
 r1 = getRunner(1, precision / 7 + 1);
 r2 = getRunner(precision / 7 + 1, 2 * precision / 7 + 1);
 r3 = getRunner(2 * precision / 7 + 1, 3 * precision / 7 + 1);
 r4 = getRunner(3 * precision / 7 + 1, 4 * precision / 7 + 1);
 r5 = getRunner(4 * precision / 7 + 1, 5 * precision / 7 + 1);
 r6 = getRunner(5 * precision / 7 + 1, 6 * precision / 7 + 1);
 Runnable r7 = getRunner(6 * precision / 7 + 1, precision);
 t1 = new Thread(r1);
 t2 = new Thread(r2);
 t3 = new Thread(r3);
 t4 = new Thread(r4);
 t5 = new Thread(r5);
 t6 = new Thread(r6);
 Thread t7 = new Thread(r7);
 t1.start();
 t2.start();
 t3.start();
 t4.start();
 t5.start();
 t6.start();
 t7.start();
 t1.join();
 t2.join();
 t3.join();
 t4.join();
 t5.join();
 t6.join();
 t7.join();
 break;
 case 8:
 r1 = getRunner(1, precision / 8 + 1);
 r2 = getRunner(precision / 8 + 1, 2 * precision / 8 + 1);
 r3 = getRunner(2 * precision / 8 + 1, 3 * precision / 8 + 1);
 r4 = getRunner(3 * precision / 8 + 1, 4 * precision / 8 + 1);
 r5 = getRunner(4 * precision / 8 + 1, 5 * precision / 8 + 1);
 r6 = getRunner(5 * precision / 8 + 1, 6 * precision / 8 + 1);
 r7 = getRunner(6 * precision / 8 + 1, 7 * precision / 8 + 1);
 Runnable r8 = getRunner(7 * precision / 8 + 1, precision);
 t1 = new Thread(r1);
 t2 = new Thread(r2);
 t3 = new Thread(r3);
 t4 = new Thread(r4);
 t5 = new Thread(r5);
 t6 = new Thread(r6);
 t7 = new Thread(r7);
 Thread t8 = new Thread(r8);
 t1.start();
 t2.start();
 t3.start();
 t4.start();
 t5.start();
 t6.start();
 t7.start();
 t8.start();
 t1.join();
 t2.join();
 t3.join();
 t4.join();
 t5.join();
 t6.join();
 t7.join();
 t8.join();
 break;
 case 12:
 r1 = getRunner(1, precision / 12 + 1);
 r2 = getRunner(precision / 12 + 1, 2 * precision / 12 + 1);
 r3 = getRunner(2 * precision / 12 + 1, 3 * precision / 12 + 1);
 r4 = getRunner(3 * precision / 12 + 1, 4 * precision / 12 + 1);
 r5 = getRunner(4 * precision / 12 + 1, 5 * precision / 12 + 1);
 r6 = getRunner(5 * precision / 12 + 1, 6 * precision / 12 + 1);
 r7 = getRunner(6 * precision / 12 + 1, 7 * precision / 12 + 1);
 r8 = getRunner(7 * precision / 12 + 1, 8 * precision / 12 + 1);
 Runnable r9 = getRunner(8 * precision / 12 + 1, 9 * precision / 12 + 1);
 Runnable r10 = getRunner(9 * precision / 12 + 1, 10 * precision / 12 + 1);
 Runnable r11 = getRunner(10 * precision / 12 + 1, 11 * precision / 12 + 1);
 Runnable r12 = getRunner(11 * precision / 12 + 1, precision);
 t1 = new Thread(r1);
 t2 = new Thread(r2);
 t3 = new Thread(r3);
 t4 = new Thread(r4);
 t5 = new Thread(r5);
 t6 = new Thread(r6);
 t7 = new Thread(r7);
 t8 = new Thread(r8);
 Thread t9 = new Thread(r9);
 Thread t10 = new Thread(r10);
 Thread t11 = new Thread(r11);
 Thread t12 = new Thread(r12);
 t1.start();
 t2.start();
 t3.start();
 t4.start();
 t5.start();
 t6.start();
 t7.start();
 t8.start();
 t9.start();
 t10.start();
 t11.start();
 t12.start();
 t1.join();
 t2.join();
 t3.join();
 t4.join();
 t5.join();
 t6.join();
 t7.join();
 t8.join();
 t9.join();
 t10.join();
 t11.join();
 t12.join();
 break;
 case 16:
 r1 = getRunner(1, precision / 16 + 1);
 r2 = getRunner(precision / 16 + 1, 2 * precision / 16 + 1);
 r3 = getRunner(2 * precision / 16 + 1, 3 * precision / 16 + 1);
 r4 = getRunner(3 * precision / 16 + 1, 4 * precision / 16 + 1);
 r5 = getRunner(4 * precision / 16 + 1, 5 * precision / 16 + 1);
 r6 = getRunner(5 * precision / 16 + 1, 6 * precision / 16 + 1);
 r7 = getRunner(6 * precision / 16 + 1, 7 * precision / 16 + 1);
 r8 = getRunner(7 * precision / 16 + 1, 8 * precision / 16 + 1);
 r9 = getRunner(8 * precision / 16 + 1, 9 * precision / 16 + 1);
 r10 = getRunner(9 * precision / 16 + 1, 10 * precision / 16 + 1);
 r11 = getRunner(10 * precision / 16 + 1, 11 * precision / 16 + 1);
 r12 = getRunner(11 * precision / 16 + 1, 12 * precision / 16 + 1);
 Runnable r13 = getRunner(12 * precision / 16 + 1, 13 * precision / 16 + 1);
 Runnable r14 = getRunner(13 * precision / 16 + 1, 14 * precision / 16 + 1);
 Runnable r15 = getRunner(14 * precision / 16 + 1, 15 * precision / 16 + 1);
 Runnable r16 = getRunner(15 * precision / 16 + 1, precision);
 t1 = new Thread(r1);
 t2 = new Thread(r2);
 t3 = new Thread(r3);
 t4 = new Thread(r4);
 t5 = new Thread(r5);
 t6 = new Thread(r6);
 t7 = new Thread(r7);
 t8 = new Thread(r8);
 t9 = new Thread(r9);
 t10 = new Thread(r10);
 t11 = new Thread(r11);
 t12 = new Thread(r12);
 Thread t13 = new Thread(r13);
 Thread t14 = new Thread(r14);
 Thread t15 = new Thread(r15);
 Thread t16 = new Thread(r16);
 t1.start();
 t2.start();
 t3.start();
 t4.start();
 t5.start();
 t6.start();
 t7.start();
 t8.start();
 t9.start();
 t10.start();
 t11.start();
 t12.start();
 t13.start();
 t14.start();
 t15.start();
 t16.start();
 t1.join();
 t2.join();
 t3.join();
 t4.join();
 t5.join();
 t6.join();
 t7.join();
 t8.join();
 t9.join();
 t10.join();
 t11.join();
 t12.join();
 t13.join();
 t14.join();
 t15.join();
 t16.join();
 break;
 case 20:
 r1 = getRunner(1, precision / 20 + 1);
 r2 = getRunner(precision / 20 + 1, 2 * precision / 20 + 1);
 r3 = getRunner(2 * precision / 20 + 1, 3 * precision / 20 + 1);
 r4 = getRunner(3 * precision / 20 + 1, 4 * precision / 20 + 1);
 r5 = getRunner(4 * precision / 20 + 1, 5 * precision / 20 + 1);
 r6 = getRunner(5 * precision / 20 + 1, 6 * precision / 20 + 1);
 r7 = getRunner(6 * precision / 20 + 1, 7 * precision / 20 + 1);
 r8 = getRunner(7 * precision / 20 + 1, 8 * precision / 20 + 1);
 r9 = getRunner(8 * precision / 20 + 1, 9 * precision / 20 + 1);
 r10 = getRunner(9 * precision / 20 + 1, 10 * precision / 20 + 1);
 r11 = getRunner(10 * precision / 20 + 1, 11 * precision / 20 + 1);
 r12 = getRunner(11 * precision / 20 + 1, 12 * precision / 20 + 1);
 r13 = getRunner(12 * precision / 20 + 1, 13 * precision / 20 + 1);
 r14 = getRunner(13 * precision / 20 + 1, 14 * precision / 20 + 1);
 r15 = getRunner(14 * precision / 20 + 1, 15 * precision / 20 + 1);
 r16 = getRunner(15 * precision / 20 + 1, 16 * precision / 20 + 1);
 Runnable r17 = getRunner(16 * precision / 20 + 1, 17 * precision / 20 + 1);
 Runnable r18 = getRunner(17 * precision / 20 + 1, 18 * precision / 20 + 1);
 Runnable r19 = getRunner(18 * precision / 20 + 1, 19 * precision / 20 + 1);
 Runnable r20 = getRunner(19 * precision / 20 + 1, precision);
 t1 = new Thread(r1);
 t2 = new Thread(r2);
 t3 = new Thread(r3);
 t4 = new Thread(r4);
 t5 = new Thread(r5);
 t6 = new Thread(r6);
 t7 = new Thread(r7);
 t8 = new Thread(r8);
 t9 = new Thread(r9);
 t10 = new Thread(r10);
 t11 = new Thread(r11);
 t12 = new Thread(r12);
 t13 = new Thread(r13);
 t14 = new Thread(r14);
 t15 = new Thread(r15);
 t16 = new Thread(r16);
 Thread t17 = new Thread(r17);
 Thread t18 = new Thread(r18);
 Thread t19 = new Thread(r19);
 Thread t20 = new Thread(r20);
 t1.start();
 t2.start();
 t3.start();
 t4.start();
 t5.start();
 t6.start();
 t7.start();
 t8.start();
 t9.start();
 t10.start();
 t11.start();
 t12.start();
 t13.start();
 t14.start();
 t15.start();
 t16.start();
 t17.start();
 t18.start();
 t19.start();
 t20.start();
 t1.join();
 t2.join();
 t3.join();
 t4.join();
 t5.join();
 t6.join();
 t7.join();
 t8.join();
 t9.join();
 t10.join();
 t11.join();
 t12.join();
 t13.join();
 t14.join();
 t15.join();
 t16.join();
 t17.join();
 t18.join();
 t19.join();
 t20.join();
 break;
 case 24:
 r1 = getRunner(1, precision / 24 + 1);
 r2 = getRunner(precision / 24 + 1, 2 * precision / 24 + 1);
 r3 = getRunner(2 * precision / 24 + 1, 3 * precision / 24 + 1);
 r4 = getRunner(3 * precision / 24 + 1, 4 * precision / 24 + 1);
 r5 = getRunner(4 * precision / 24 + 1, 5 * precision / 24 + 1);
 r6 = getRunner(5 * precision / 24 + 1, 6 * precision / 24 + 1);
 r7 = getRunner(6 * precision / 24 + 1, 7 * precision / 24 + 1);
 r8 = getRunner(7 * precision / 24 + 1, 8 * precision / 24 + 1);
 r9 = getRunner(8 * precision / 24 + 1, 9 * precision / 24 + 1);
 r10 = getRunner(9 * precision / 24 + 1, 10 * precision / 24 + 1);
 r11 = getRunner(10 * precision / 24 + 1, 11 * precision / 24 + 1);
 r12 = getRunner(11 * precision / 24 + 1, 12 * precision / 24 + 1);
 r13 = getRunner(12 * precision / 24 + 1, 13 * precision / 24 + 1);
 r14 = getRunner(13 * precision / 24 + 1, 14 * precision / 24 + 1);
 r15 = getRunner(14 * precision / 24 + 1, 15 * precision / 24 + 1);
 r16 = getRunner(15 * precision / 24 + 1, 16 * precision / 24 + 1);
 r17 = getRunner(16 * precision / 24 + 1, 17 * precision / 24 + 1);
 r18 = getRunner(17 * precision / 24 + 1, 18 * precision / 24 + 1);
 r19 = getRunner(18 * precision / 24 + 1, 19 * precision / 24 + 1);
 r20 = getRunner(19 * precision / 24 + 1, 20 * precision / 24 + 1);
 Runnable r21 = getRunner(20 * precision / 24 + 1, 21 * precision / 24 + 1);
 Runnable r22 = getRunner(21 * precision / 24 + 1, 22 * precision / 24 + 1);
 Runnable r23 = getRunner(22 * precision / 24 + 1, 23 * precision / 24 + 1);
 Runnable r24 = getRunner(23 * precision / 24 + 1, precision);
 t1 = new Thread(r1);
 t2 = new Thread(r2);
 t3 = new Thread(r3);
 t4 = new Thread(r4);
 t5 = new Thread(r5);
 t6 = new Thread(r6);
 t7 = new Thread(r7);
 t8 = new Thread(r8);
 t9 = new Thread(r9);
 t10 = new Thread(r10);
 t11 = new Thread(r11);
 t12 = new Thread(r12);
 t13 = new Thread(r13);
 t14 = new Thread(r14);
 t15 = new Thread(r15);
 t16 = new Thread(r16);
 t17 = new Thread(r17);
 t18 = new Thread(r18);
 t19 = new Thread(r19);
 t20 = new Thread(r20);
 Thread t21 = new Thread(r21);
 Thread t22 = new Thread(r22);
 Thread t23 = new Thread(r23);
 Thread t24 = new Thread(r24);
 t1.start();
 t2.start();
 t3.start();
 t4.start();
 t5.start();
 t6.start();
 t7.start();
 t8.start();
 t9.start();
 t10.start();
 t11.start();
 t12.start();
 t13.start();
 t14.start();
 t15.start();
 t16.start();
 t17.start();
 t18.start();
 t19.start();
 t20.start();
 t21.start();
 t22.start();
 t23.start();
 t24.start();
 t1.join();
 t2.join();
 t3.join();
 t4.join();
 t5.join();
 t6.join();
 t7.join();
 t8.join();
 t9.join();
 t10.join();
 t11.join();
 t12.join();
 t13.join();
 t14.join();
 t15.join();
 t16.join();
 t17.join();
 t18.join();
 t19.join();
 t20.join();
 t21.join();
 t22.join();
 t23.join();
 t24.join();
 break;
 }
 /* if (threadCount == 1) {
 Runnable r1 = getRunner(1, precision);
 Thread t1 = new Thread(r1);
 t1.start();
 t1.join();
 }*/
 /* Runnable r1 = getRunner(1, calculation + 1);
 Runnable r2 = getRunner(calculation + 1, 2 * calculation + 1);
 Runnable r3 = getRunner(2 * calculation + 1, 3 * calculation + 1);
 Runnable r4 = getRunner(3 * calculation + 1, 4 * calculation);
 Thread t1 = new Thread(r1);
 t1.start();
 Thread t2 = new Thread(r2);
 t2.start();
 Thread t3 = new Thread(r3);
 t3.start();
 Thread t4 = new Thread(r4);
 t4.start();
 t1.join();
 t2.join();
 t3.join();
 t4.join();*/
 System.out.println("e = " + result);
 long stop = System.currentTimeMillis();
 long diff = stop - start1;
 System.out.println("Time: " + diff + " ms");
 System.out.println("Count of Threads: " + threadCount);
 System.out.println("Precision: " + precision);
 }
}
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Jun 9, 2014 at 18:55
\$\endgroup\$

4 Answers 4

7
\$\begingroup\$

Which is faster, switch or for/while loop?

The speed difference for you here regarding a switch or a for/while loop is nothing compared to the rest of your code. You should really not be worried about that here.

That being said, I believe a switch is technically faster, but as I said. You shouldn't worry about that there!

You should be worried about maintainability, flexibility and readability. In which case a for-loop is substantively better.

Unexpected Results without Error Messages

Imagine the user currently inputting "10" as the number of threads. Then what happens? E becomes 1. No error message. This can be very confusing for a user (Based on a true story). Your current switch approach does not support that option.

To fix this, either a) Add a default statement to your switch, stating that the chosen number of threads is not a valid option. b) Add support for it by using a for-loop instead!

Get rid of the static habit!

Instead of getting used to static, create an instance of your class and pass the required variables to it's constructor (such as precision and threadCount) and then use a non-static method to make the computations.

I think that the reason you're using static is that it's the "easiest/fastest" approach. But I'm warning you: It might come around and haunt you. I recommend avoiding over-using static.

By using the non-static approach and passing arguments to the constructor, you can mark several fields as final which is considered a good practice when possible.

Unused variables

static int numberOfThread = 4;
int calculation = precision / threadCount;

These variables does not seem to be used. Remove them.

Other comments

  • Use BigDecimal.ONE instead of new BigDecimal("1")
  • Instead of computing time with System.currentTimeMillis(); use System.nanoTime();
  • Create and return on same line. Instead of Runnable runner = new Runnable... you can return new Runnable...
  • You have some commented code without explaining why it is commented. Remove that code next time before posting it for review to reduce confusion.

Once again though, most importantly:

Don't use switch here, use for!

(See answer by @VoiceOfUnreason)

answered Jun 10, 2014 at 18:02
\$\endgroup\$
6
\$\begingroup\$

You should write out your code so that what you are trying to do is clear. In this case, there are a number of distinct steps

  1. Create a bunch of Runnable
  2. Start them all
  3. Wait until they have all finished
  4. Report the result

For part #1 -- you commented out Runnable[] but that was close to the right idea. I would instead recommend a List

List<Runnable> tasks = new ArrayList();
for (int i = 0; i < threadCount; ++i) {
 int low = 1 + (i * precision / threadCount);
 int high = 1 + ((i+1) * precision / threadCount);
 tasks.add( getRunner(low,high) ) ;
}

For part #2 -- create an instance of an ExecutorService, and submit all of the tasks to it. There are a number of different ExecutorService implementations, with different strategies to determine how they are run. Your implementation suggests that you want everything on a thread of its own, so perhaps

ExecutorService executor = Executors.newFixedThreadPool(threadCount);
for(Runnable task : tasks) {
 executor.submit(task);
}

For part #3, you can signal to the executor service that all tasks have been submitted, and then wait until they all finish.

// let the service know that all tasks are submitted
executor.shutdown();
executor.awaitTermination(...);

You're likely to have contention on the addResult() method, because all of the worker threads need to block waiting for each other to do that part of the calculation. You might get a small improvement by writing the intermediate results to a thread safe queue, and adding another task that reads the events out of that queue to do the addition.

There are data structures, like a ring buffer, that can handle the thread contention more easily. Take a look at Disruptor, which is a library specifically designed for many threads writing data to one single consuming thread.

Malachi
29k11 gold badges86 silver badges188 bronze badges
answered Jun 9, 2014 at 19:24
\$\endgroup\$
1
  • \$\begingroup\$ Is it normal for precision = 10000 and 1 thread that the program never gets build? \$\endgroup\$ Commented Jun 10, 2014 at 18:14
5
\$\begingroup\$

Your I/O is eccentric.

args[0], args[2], and args[4] are ignored. args[5] is also required, but the program never does anything with it.

Code in main() should be kept to a minimum — just enough to process the arguments. There should be another method, such as public static BigDecimal e(int precision, int threads) that does the "real" work, so that your class can be called by other code in the future.

Hard-coding result.txt is user-unfriendly and limits the reusability of your code. I suggest printing your diagnostics to System.err and the output to System.out. Let the user redirect System.out to a file using the shell, if desired. Your program shouldn't have to worry about such things.

The thread-spawning code really ought to be generalized. There should be an array of Threads rather than a large number of Thread variables.

Calculating factorial() from scratch is wasted work. You should be able to compute factorials based on factorials computed in previous terms.

Consider other algorithms for calculating e.

answered Jun 9, 2014 at 19:20
\$\endgroup\$
1
  • \$\begingroup\$ can you give me some idea how to rewrite factorial(),because i should use this kind of calculation .Thanks! \$\endgroup\$ Commented Jun 10, 2014 at 18:12
3
\$\begingroup\$

Be careful with MathContext: you are creating a new object at each addition operation which could really lower your performance.

Here is another replacement for your switch statement using Java 8's Stream. I don't really recommend using this at the moment since it is very new and few Java programmers know about Streams. I also used some "functional" programming concepts from Java 8, so some part of the code might be completely incomprehensible if you are not used to that style of programming.

I am also using a CountDownLatch instead of all the join()'s. This feature has existed since Java 5. However, using Threads and CountDownLatches is kind of old fashioned and you should instead consider using Executors and such from the java.util.concurrent packages.

 MathContext mathContext = new MathContext(1000, RoundingMode.HALF_UP);
 CountDownLatch countDownLatch = new CountDownLatch(nThreads);
 IntStream.range(0, nThreads).forEach(i -> {
 new Thread(() -> {
 int startIndex = i * precision / nThreads + 1;
 int endIndex = (i + 1) * precision / nThreads + 1;
 if (i == nThreads - 1)
 endIndex--;
 Stream<BigDecimal> bigDecims = IntStream.range(startIndex, endIndex)
 .mapToObj(j -> BigDecimal.valueOf(3 * 3 * j * j + 1).divide(factorial(3 * j)));
 BigDecimal total = bigDecims
 .reduce(BigDecimal.valueOf(0), (x, y) -> x.add(y, mathContext));
 addResult(total);
 countDownLatch.countDown();
 }).start(); 
 });
 countDownLatch.await();
Malachi
29k11 gold badges86 silver badges188 bronze badges
answered Jun 10, 2014 at 20:30
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.