1

Will generate performance problems using functions of this style?:

*fun sqrt(x: Float) = Math.sqrt(x.toDouble()).toFloat()*

*fun cos(angle: Float) = Math.cos(angle.toDouble()).toFloat()*

*fun sin(angle: Float) = Math.sin(angle.toDouble()).toFloat()*

for using it so with Floats:

*sqrt(45.0f)*

*cos(1.58f)*

*sin(0.28f)*

instead of the much more verbose:

*Math.sqrt(45.0f.toDouble()).toFloat()*

*Math.cos(1.58f.toDouble()).toFloat()*

*Math.sin(0.28f.toDouble()).toFloat()*

Greetings and thanks in advance

jjvr
  • 85
  • 1
  • 7
  • duplicate? http://stackoverflow.com/questions/13263948/fast-sqrt-in-java-at-the-expense-of-accuracy – Meiko Rachimow Mar 08 '16 at 08:07
  • It's not really a duplicate because in Java you can implicitly cast a Float to a Double but in Kotlin there is no implicit casting so interacting with the Java Math library gets real ugly real quick. – CaseyB Mar 08 '16 at 14:56

4 Answers4

2

There should be NO performance problem in using the wrappers.

The performance may be slightly less due to calling those functions (they are statically dispatched, just like any utility methods).

If you use the wrappers in the hot code then you can inline them:

inline fun sqrt(x: Float) = Math.sqrt(x.toDouble()).toFloat()

For inlined functions the byte-code is No different to the one Java generates.

voddan
  • 31,956
  • 8
  • 77
  • 87
  • the JVM should notice these if they are a hot code-path and inline them for you, there is no gain from manually inlining them bigger than what hotspot would already decide. On Android, maybe not. So inline would help in the Android case, less on the JVM outside of Android case. – Jayson Minard Mar 09 '16 at 00:24
  • Agreed. The "hotter" the path, the less the gain – voddan Mar 09 '16 at 07:15
1

I think there is no problem using the Math class. In earlier Android versions there was a class android.util.FloatMath which handles float arithmetic, but the common Math class is faster now and the class is deprecated.

Historically these methods were faster than the equivalent double-based Math methods. On versions of Android with a JIT they became slower and have since been re-implemented to wrap calls to Math. Math should be used in preference. All methods were removed from the public API in version 23.

http://developer.android.com/reference/android/util/FloatMath.html

Christopher
  • 9,682
  • 7
  • 47
  • 76
0

As I understand performance, it is measured by the complexity of the algorithm.
An algorithm over an array of n elements, performing 1 operation on each, it is said to be of O(n) complexity.
The same algorithm complexity, performing 3 operations on each element is still O(n)
A fixed operation, like .toFloat or .toDouble() will not affect performance, since those are of O(1) complexity.

ilomambo
  • 8,290
  • 12
  • 57
  • 106
  • However there is not a 1:1 relationship between algorithm complexity and performance. An algo might still be the same O-notation order as another, but be slower in execution. For instance, there is only one operation on each, but op A takes longer than op B in the hardware layer for instance... – Richard Tyregrim Mar 08 '16 at 09:08
  • @RichardEriksson Yes, you are correct. In the real world 3 multiplications take 3 times the time of a single multiplication. But unless you are dealing with a lot of operations, the impact on the perceived time should be unnoticeable. – ilomambo Mar 08 '16 at 09:15
  • 1
    I believe this is not what was the question about – voddan Mar 08 '16 at 11:52
0

In fact, trying:

var iniTemp = System.currentTimeMillis()
for (i in 1..10000000)
  sqrt(755.369f)
d((System.currentTimeMillis() - iniTemp).toString())

407 milisecs

and:

var iniTemp = System.currentTimeMillis()
for (i in 1..10000000)
  Math.sqrt(755.369f.toDouble()).toFloat()
d((System.currentTimeMillis() - iniTemp).toString())

317 milisecs

both in an older Nexus 7

Thanks

jjvr
  • 85
  • 1
  • 7