0

I need to convert double to boolean in java. It is happening very often in my application and it has the crucial effect on the performance of the application. Is there any way how to rewrite this method to be faster? I need to operate with doubles because precision is necessary, but instead of saving doubles, I save just boolean values (when the data can be only 0 or 1). The code is here:

    public static double booleanToDouble(boolean b) {
        if (b) {
            return 1;
        }
        return 0;
    }

In my opinion, this is not XY problem. The whole run of application for 50 000 000 rows of data needs 3 seconds. With this conversion, the time grows up to 5 seconds approximately. So two seconds are necessary for this conversion and it is almost half of the whole application run.

Ján Яabčan
  • 743
  • 2
  • 10
  • 20
  • 1
    Possible [XY Problem](http://xyproblem.info/)? – Hovercraft Full Of Eels Apr 14 '18 at 20:34
  • 3
    This, `"I need to operate with doubles because precision is necessary"`, seems backwards. I usually try to *avoid* doubles when I need very high precision. – Hovercraft Full Of Eels Apr 14 '18 at 20:35
  • 2
    `it has the crucial effect on the performance of the application` - I doubt that very much. `I need to operate with doubles because precision is necessary,` - your other math calculations will be far more time consuming that a simple conversion. Just make sure you only do the conversion once for each set of data you work on. – camickr Apr 14 '18 at 20:36
  • @HovercraftFullOfEels "*I usually try to avoid doubles when I need very high precision*" - could you elaborate? – Turing85 Apr 14 '18 at 20:43
  • Yes, possible XY problem. You may want to tell us your actual problem instead of a speculated solution that you think might solve your original problem. It doesn't really make a difference in code efficiency by changing your current code. – user3437460 Apr 14 '18 at 20:43
  • 1
    @Turing85: take financial calculations as an example, and then check out this SO post: [Why not use Double or Float to represent currency?](https://stackoverflow.com/questions/3730019/why-not-use-double-or-float-to-represent-currency/) – Hovercraft Full Of Eels Apr 14 '18 at 20:45
  • 1
    @HovercraftFullOfEels ah okay ^^ that is somewhat of a special case since this deals with some finite amount of decimal places. Thought you were talking wrt. arbritary decimal places. – Turing85 Apr 14 '18 at 20:46
  • I don't think, that it is XY problem. Look at the question, I updated it. – Ján Яabčan Apr 14 '18 at 20:53
  • 1
    You might want to try inlining this code instead of calling a method – Marged Apr 14 '18 at 20:54
  • The information that you gave does not tell us in any way whether this is an XY problem or not. Please read the link. The only way to know if it's an XY Problem is to know what behavior you're trying to achieve, since for all we know you could be going about it in an entirely wrong way. – Hovercraft Full Of Eels Apr 14 '18 at 20:55
  • is there some difference between inline code and calling of methods? – Ján Яabčan Apr 14 '18 at 20:56
  • @Marged you should not try to outsmart the JIT compiler. If it deems it necessary, the JIT will inline the code for you. – Turing85 Apr 14 '18 at 21:02
  • @Turing85 I would say a strange problem allows for a strange solution. And it is only an attempt, if this improves the performance, there is always room for a second thought. – Marged Apr 14 '18 at 21:05
  • 1
    `The whole run of application for 50 000 000 rows of data` - if you need data for 50M rows of data you need to get that data from somewhere. That data will not be sitting in memory. The time to convert a boolean to a double will be infinitely small compared to the time to access the data. – camickr Apr 14 '18 at 21:16
  • Have you tried asking b > 0 instead of forcing the core to do the convertion? I'm assuming b id always double and can not be null or non numeric. Also can be b !== 0 if u r working with negatives – Gonzalo Apr 14 '18 at 21:23
  • @camickr, yes it is true. This is only small mathematical operation. Only I need is to multiply two vectors. These vectors are saved in special structures. But this question was stupid from me. It works really good and the speed is not bad. Users cannot seem some difference. But I was only interesting if it is possible to improve this casting. – Ján Яabčan Apr 14 '18 at 21:37

3 Answers3

7

Although I cannot imagine the use-case, you could use a ternary operator everywhere instead of calling a function:

b ? 1d : 0d;

M. le Rutte
  • 3,525
  • 3
  • 18
  • 31
2

The most likely cause of the quoted code taking significant time is mispredicted branches. Any time the processor has to deal with a conditional branch, including in a ternary operator, it has to guess whether the branch will be taken or not. If it gets it wrong, it has to throw away calculations and pipeline contents, which can cost many cycles.

Consider storing the data as a byte rather than a boolean. The conversion would be a simple integer to double conversion, with no branches.

Patricia Shanahan
  • 25,849
  • 4
  • 38
  • 75
  • Interesting idea. But there is a risk that you would just push the branch prediction failure somewhere else. You would need to do a careful analysis of the contexts where this method is called. – Stephen C Apr 15 '18 at 00:42
  • @StephenC Yes, it is very, very important that the data actually be stored and read as a numeric type, not boolean. If it is stored and read as boolean, the branch prediction issue will arise wherever it is converted to a numeric type. – Patricia Shanahan Apr 15 '18 at 02:27
1

IMO, it is unlikely that you will improve on the performance of this by micro-optimizing it. But you could try:

  • You could try using the ternary operator instead of if ... else. The JIT compiler should treat the two forms as the same and produce equivalent native code for them. But it might not.

  • Patricia Shanahan's idea could work; see https://stackoverflow.com/a/49837300/139985

  • This method should be small enough for the JIT compiler to automatically inline the method at the native code level. But you could inline the code by hand by replacing calls to the method with the method's body.


You seem to have done some measurement, and that this is the basis of your decision that this section of the code needs to be optimized.

I would advise you to carefully look at your benchmarking methodology. Make sure that your results are not being distorted by the effects of JVM warmup or GC1.


You commented:

Only I need is to multiply two vectors. These vectors are saved in special structures. But this question was stupid from me. It works really good and the speed is not bad. Users cannot seem some difference. But I was only interesting if it is possible to improve this casting.

Standard advice on optimization is to spend your effort where it is actually needed. In this case:

  • If the users think it is fast enough, that should be good enough.
  • If they don't, then benchmark and profile so that:
    1. you can decide if this is the part of the codebase that you should be optimizing,
    2. you can measure the effects of your optimization ... reliably, and
    3. you can know when to stop.

1 - When someone quotes figures where the times measured are just a few seconds, there is always the risk that these represent once-off measurements rather than averages of multiple repetitions in a warmed up JVM.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216