In Java Math Package, there is a pow function with returns double type. However, we can speed up this if only integer (long type) parameters are required, i.e. compute integer power
The first version is easy, complexity of
1 2 3 4 5 6 7 | public static long pow1(long a, long b) { long re = 1; while (b-- > 0) { re *= a; } return re; } |
public static long pow1(long a, long b) { long re = 1; while (b-- > 0) { re *= a; } return re; }
The second version reduces the complexity by
1 2 3 4 5 6 7 8 9 10 11 | public static long pow2(long a, long b) { long re = 1; while (b > 0) { if ((b & 1) == 1) { re *= a; } b >>= 1; a *= a; } return re; } |
public static long pow2(long a, long b) { long re = 1; while (b > 0) { if ((b & 1) == 1) { re *= a; } b >>= 1; a *= a; } return re; }
The third version would be to use the inbuilt (long)Math.pow(). The fourth version would be to leave the return-value as double (without type casting).
We use the System.currentTimeMillis() to measure the time differences for above four versions. The whole Java code is:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | public class Test { private static long[] arr = new long[10000000]; private static double[] arr2 = new double[10000000]; public static long pow1(long a, long b) { long re = 1; while (b-- > 0) { re *= a; } return re; } public static long pow2(long a, long b) { long re = 1; while (b > 0) { if ((b & 1) == 1) { re *= a; } b >>= 1; a *= a; } return re; } public static void main(String[] args) { final long startTime1 = System.currentTimeMillis(); for (int i = 0; i < arr.length; i ++) { arr[0] = pow1(2, 64); } final long endTime1 = System.currentTimeMillis(); final long startTime2 = System.currentTimeMillis(); for (int i = 0; i < arr.length; i ++) { arr[0] = pow2(2, 64); } final long endTime2 = System.currentTimeMillis(); final long startTime3 = System.currentTimeMillis(); for (int i = 0; i < arr.length; i ++) { arr[0] = (long)Math.pow(2, 64); } final long endTime3 = System.currentTimeMillis(); final long startTime4 = System.currentTimeMillis(); for (int i = 0; i < arr.length; i ++) { arr2[0] = Math.pow(2, 64); } final long endTime4 = System.currentTimeMillis(); System.out.println("Total execution time (pow1): " + (endTime1 - startTime1) ); System.out.println("Total execution time (pow2): " + (endTime2 - startTime2) ); System.out.println("Total execution time ((long)Math.pow): " + (endTime3 - startTime3) ); System.out.println("Total execution time (Math.pow): " + (endTime4 - startTime4) ); } } |
public class Test { private static long[] arr = new long[10000000]; private static double[] arr2 = new double[10000000]; public static long pow1(long a, long b) { long re = 1; while (b-- > 0) { re *= a; } return re; } public static long pow2(long a, long b) { long re = 1; while (b > 0) { if ((b & 1) == 1) { re *= a; } b >>= 1; a *= a; } return re; } public static void main(String[] args) { final long startTime1 = System.currentTimeMillis(); for (int i = 0; i < arr.length; i ++) { arr[0] = pow1(2, 64); } final long endTime1 = System.currentTimeMillis(); final long startTime2 = System.currentTimeMillis(); for (int i = 0; i < arr.length; i ++) { arr[0] = pow2(2, 64); } final long endTime2 = System.currentTimeMillis(); final long startTime3 = System.currentTimeMillis(); for (int i = 0; i < arr.length; i ++) { arr[0] = (long)Math.pow(2, 64); } final long endTime3 = System.currentTimeMillis(); final long startTime4 = System.currentTimeMillis(); for (int i = 0; i < arr.length; i ++) { arr2[0] = Math.pow(2, 64); } final long endTime4 = System.currentTimeMillis(); System.out.println("Total execution time (pow1): " + (endTime1 - startTime1) ); System.out.println("Total execution time (pow2): " + (endTime2 - startTime2) ); System.out.println("Total execution time ((long)Math.pow): " + (endTime3 - startTime3) ); System.out.println("Total execution time (Math.pow): " + (endTime4 - startTime4) ); } }
with the result:
Wow, the second version is fastest, around 4-5 times faster than the first naive version. The first version is even faster than the Math.pow() with or without type casting (which doesn’t make much differences).
The same principle also applies to other programming languages, such as C/C++ although the performance speed-ups may vary slightly.
Relevant Post:
[1] helloacm.com/compute-powermod-abn/
–EOF (Coding For Speed) —
Product Recommendations
- Make Your WordPress Fast Again! This WordPress is accelerated by WP Rocket Plugin!
- Free $10 Credit, when you sign up with Vultr Cloud VPS (4 Months Giveaway!)
- Free $10 Credit, when you sign up with Digital Ocean Cloud VPS (2 Months Giveaway!)
- Free $20 Credit, when you sign up with Linode Cloud VPS (4 Months Giveaway!) - (Coupon: PodCastInit2022)
- The easiest way to Buy and Sell Bitcoins/Litecoins via Wirex Visa Debit Card!
- Buy and Sell Bitcoins/Litecoins via Local Bitcoins