Paranoia performance: how much does Float.parseFloat (String), Integer.parseInt (String) cost?

I recently used JSON to store configuration settings for a certain number of subclasses of the same class. To maintain a consistent interface, I have provided the parent class to the public methods void setParameter(String, String) and String getParameter(String) . Then each subclass puts the provided parameters in its own type and does some calculation with them.

Now I wonder: since I already store each parameter inside the HashMap, does it really make sense to keep a separate field with the correct type for each parameter? What is the computational overhead of converting String parameters to their native type every time I need them, given that I need to use them very often?

Thanks,
Tunnuz

+4
source share
3 answers

I suggest you check this out. This is a fairly expensive operation if you need to do this many times, but it can be cheaper than Double.toString () or Integer.toString () if you used them to create data in the first place.

I also suggest using only double if you don't know that using float never cause a rounding problem .;)

It's about as expensive as creating objects like String, or adding an entry to a HashMap. If you do not plan to avoid this, I would not worry about it.

EDIT: As with the @Stackers test, I would continue the test and use nanoTime ()

 int runs = 10000000; String val = "" + Math.PI; long start = System.nanoTime(); for (int i = 0; i < runs; i++) Float.parseFloat(val); long time = (System.nanoTime() - start) / runs; System.out.println("Average Float.parseFloat() time was " + time + " ns."); long start2 = System.nanoTime(); for (int i = 0; i < runs; i++) Double.parseDouble(val); long time2 = (System.nanoTime() - start2) / runs; System.out.println("Average Double.parseDouble() time was " + time2 + " ns."); 

prints

 Average Float.parseFloat() time was 474 ns. Average Double.parseDouble() time was 431 ns. 

BTW: I have a function that reads doubles from a direct ByteBuffer, which takes 80 ns. This is faster because it does not need a string, and it does not create any objects. However, this is by no means trivial, and you should develop your basic system to avoid creating any object.;)

+5
source

Measurement is as easy as:

 public class PerfTest { public static void main(String[] args) { String val = "" + (float) Math.PI; long start = System.currentTimeMillis(); for ( int i = 0 ; i < 100000 ; i++ ) { Float.parseFloat( val ); } System.out.println( System.currentTimeMillis() - start + " ms." ); } } 

62 ms for 100,000 iterations.

+3
source

fwiw the microchips above seem a little unsafe, you expect the access point to detect that val never changes and is never used. Another thing to keep in mind is that there are times when the averages (from two realizations) can be close to each other in absolute terms, but where 1 has a rather bad tail cost compared to the other, for example. your 90th percentile may be very similar, but the last 10% is much worse.

For example, changing it each time to use a different value, and resetting the value to stderr, gives a slightly higher average cost (~ 3300ns versus ~ 2500ns for the case when the value is reused) on my mailbox. This is much higher than other messages, apparently because it actually takes a certain amount of time to actually get the time, so the measurement is artificially high. It just shows one of the difficulties when using a good micro-object.

It can also be noted that I can not measure the effect that, as I suggested, may be present, for example. if he were present, you could expect him to be fully optimized. I suppose you could see what happens through LogCompilation if you are really interested.

  int runs = 10000000; long totalTime = 0; for (int i = 0; i < runs; i++) { String val = "" + Math.random(); long start = System.nanoTime(); float f = Float.parseFloat(val); long end = System.nanoTime(); System.err.println(f); totalTime += (end-start); } long time = totalTime / runs; totalTime = 0; for (int i = 0; i < runs; i++) { String val = "" + Math.random(); long start = System.nanoTime(); double d = Double.parseDouble(val); long end = System.nanoTime(); System.err.println(d); totalTime += (end-start); } long time2 = totalTime / runs; System.out.println("Average Float.parseFloat() time was " + time + " ns."); System.out.println("Average Double.parseDouble() time was " + time2 + " ns."); 
+3
source

Source: https://habr.com/ru/post/1346689/


All Articles