JDK-4477961 : java.lang.Math.toDegrees(double) could be optimized
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 1.3.0
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2001-07-10
  • Updated: 2019-03-04
  • Resolved: 2014-09-23
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9 b33Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
Name: bsC130419			Date: 07/09/2001


java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)

The source code for java.lang.Math.toDegrees(double) is as follows:

    public static double toDegrees(double angrad) {
	return angrad * 180.0 / PI;
    }

Notice that the expression 180.0 / PI is effectively a constant.  However,
because Java performs calculations from left to right, the multiplication is
performed first, and then the division is performed.  This could be optimized
by enclosing 180.0 / PI in parenthesis as follows:

    public static double toDegrees(double angrad) {
	return angrad * (180.0 / PI);
    }

The compiler and/or hotspot will recognize the result of the division as a
constant and only calculate it once.  This avoids an expensive division
operation for each call to toDegrees().

However, one caveat is that this may affect the results of some calculations.
For example, some range of numbers that used to overflow to infinity by
performing the multiplication by 180, will now not overflow and will return a
valid result.  As well, by pre-computing 180.0/PI, we may affect the precision
of the result.  In my tests, however, the result was identical and is 350%
faster with the parenthesis.

The same issue exists in java.lang.StrictMath.toDegrees(double).

Along the same lines, java.lang.Math.toRadians(double) is implemented as
follows:

    public static double toRadians(double angdeg) {
	return angdeg / 180.0 * PI;
    }

This could be reworked for better performance as follows:

    public static double toRadians(double angdeg) {
	return angdeg * (PI / 180.0);
    }

This performs the division only once (probably at compile-time).  Each call to
toRadians() now only has to perform one multiplication instead of a division
AND multiplication before.  In my tests, this change also had a 350% increase
in performance without affecting the results.

The same issue exists with java.lang.StrictMath.toRadians().
(Review ID: 127319) 
======================================================================
###@###.### 2004-11-11 22:25:06 GMT

Comments
Review thread: http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-September/028855.html
22-09-2014

The proposed change improves the performance of both methods in question by more than a factor of three, as measured by the Java Microbenchmark Harness (JMH). Before: Benchmark Mode Samples Mean Mean error Units o.s.ToAngularCoordinates.toDegrees avgt 10 4.293 0.039 ns/op o.s.ToAngularCoordinates.toRadians avgt 10 4.299 0.056 ns/op After: Benchmark Mode Samples Mean Mean error Units o.s.ToAngularCoordinates.toDegrees avgt 10 1.125 0.068 ns/op o.s.ToAngularCoordinates.toRadians avgt 10 1.104 0.015 ns/op
22-09-2014

Apparently given a double constant c and its inverse cInv = 1.0/C, then for a double value y, the result of the division double xDiv = y / c; is the same as the result xFma defined by double t = y * cInv; double r = -fma(c, t, -y); double xFma = fma(r, cInv, t); where fma() is the fused multiply-add function. Depending on the system, the computation of xFma may be faster than the computation of xDiv.
24-07-2014

CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: dragon
14-06-2004

WORK AROUND Name: bsC130419 Date: 07/09/2001 Implement your own toDegrees() and toRadians() methods for performance improvements. ======================================================================
11-06-2004

EVALUATION Worth looking into any changes in numerical properties; as bug filer notes, the vesion without a runtime divide should run much faster. ###@###.### 2002-04-29 To preserve accuracy, will look into multiplying by a constant split into two values, a la Dekker's tricks. ###@###.### 2002-06-13 Deferring until Tiger. ###@###.### 2002-11-14 Will reconsider for a post-Tiger release. ###@###.### 2003-09-30
13-06-2002