2

In a Java environment, which performs better?

a)

public void eventHandler(SomeEvent event) {
    event.getPlayer().doThis();
    event.getPlayer().doThat();
    event.getPlayer().alsoThis();
    event.getPlayer().getStats().addStat("foo", 1);
    event.getPlayer().getStats().addStat("bar", 1337);
}

b)

public void eventHandler(SomeEvent event) {
    Player player = event.getPlayer();
    player.doThis();
    player.doThat();
    player.alsoThis();
    PlayerStats stats = player.getStats();
    stats.addStat("foo", 1);
    stats.addStat("bar", 1337);
}
  • The SomeEvent class is an immutable snapshot of something that just happend and will always return the same values via its getter-methods
  • In both scenarios, we will assume that event and event.getPlayer() are guranteed to never be null.
  • We will also assume that both Event#getPlayer() and Player#getStats() are not performing any calculations, but instead are just returning a referenced object.
  • Naturally, there could be even more method calls - it's just an example.

By gut feeling, i have so far assumed that option b) would be consuming less CPU power and therefore more RAM during the execution of the method. And since the environment i usually work in, usually has a higher abundance of RAM and the processes are tied to non-async single-core threads, i have also usually gone with b) as a habit.

Is there anything to that? Does it even make a significant difference other than maybe a few nanoseconds? Or is there maybe an option c) i should be going with instead?

P.S.: Yes, i am aware that i may be worrying about negliable performance improvements with this. But if either way does make an even ever so slight difference, i don't see anything wrong with turning it into a habit while writing my code.

jaylawl
  • 105
  • 6
  • In my experience, there is no performance impact because the JIT compiler manages to basically inline it. That said, I prefer the second style, but it's pretty much a matter of taste. – daniu Jan 22 '21 at 09:04
  • 1
    The main problem with the first approach is that `event.getPlayer()` might actually return different values on each call - you say it is guaranteed to never return null, but we only have your word on that ;-). The compiler and optimizer don't know that in general and can't rely on that, so some optimizations won't be possible. – Hulk Jan 22 '21 at 09:05
  • It also needlessly duplicates code - if you decide to rename the method `getPlayer()`, this will change all lines in the first version, but only one line in the second version. This can make diffs a bit harder to read. – Hulk Jan 22 '21 at 09:07
  • @Hulk in this case `event.getXYZ()` would always return the same object respectively, as the `event` would be an immutable snapshot of something that just happened. i will add this to the clarifications :-) thanks for pointing it out – jaylawl Jan 22 '21 at 09:11
  • 1
    If you use a static analyzer, this may also lead to lots of problems to be reported about possible states that do not really happen in your application - but a static analyzer cannot, in general, know that - see for example https://stackoverflow.com/questions/64170732/sonar-possible-null-pointer-dereference-due-to-return-value-of-called-method – Hulk Jan 22 '21 at 09:11
  • 1
    You "know" that, but that is basically "only" the documented contract - nothing in the code prevents the `event` from being mutable at runtime. If the `SomeEvent` class is modified in the future (or a different `SomeEvent` class is loaded at runtime), nothing will tell you that the assumptions this code is based upon no longer hold. – Hulk Jan 22 '21 at 09:19
  • @Hulk i think i see where you're going, but i only stated those assumptions for the benefit of the core question, which is the performance. of course the situation in which elements can change is possible and requires thought to it, but that's going way-past what the question is about. i appreciate the caution though. – jaylawl Jan 22 '21 at 09:26

0 Answers0