简体   繁体   English

Java中更好/更快的是:2个方法调用或1个对象调用

[英]What is better/faster in Java: 2 method calls or 1 object call

I'm afraid this is a terribly stupid question. 我担心这是一个非常愚蠢的问题。 However, I can't find an answer to it and therefore require some help :) 但是,我找不到答案,因此需要一些帮助:)

Let's start with a simplification of my real problem: 让我们从简化我的真实问题开始:

Assume I have a couple of boxes each filled with a mix of different gems. 假设我有几个盒子,每个盒子都装满了不同的宝石。

I'm now creating an object gem which has the attribute colour and a method getColour to get the colour of the gem. 我现在正在创建一个具有属性颜色的对象gem和一个getColour方法来获取gem的颜色。 Further I'm creating an object box which has a list of gems as attribute and a method getGem to get a gem from that list. 此外,我正在创建一个对象框,其中包含一个gems列表作为属性,另一个方法getGem用于从该列表中获取gem。

What I want to do now is to count all gems in all boxes by colour. 我现在要做的是按颜色计算所有框中的所有宝石。 Now I could either do something like 现在我可以做类似的事情

int sapphire = 0;
int ruby = 0;
int emerald = 0;

for(each box = i)
    for(each gem = j)
        if(i.getGem(j).getColour().equals(“blue”)) sapphire++;
        else if(i.getGem(j).getColour().equals(“red”)) ruby++;
        else if(i.getGem(j).getColour().equals(“green”)) emerald++;

or I could do 或者我能做到

int sapphire = 0;
int ruby = 0;
int emerald = 0;
String colour;

for(each box = i)
    for(each gem = j)
        colour = i.getGem(j).getColour();
        if(colour.equals(“blue”)) sapphire++;
        else if(colour.equals(“red”)) ruby++;
        else if(colour.equals(“green”)) emerald++;

My question is now if both is essentially the same or should one be preferred over the other? 我现在的问题是,两者基本相同还是优先于另一个? I understand that a lot of unnecessary new string objects are produced in the second case, but do I get a speed advantage in return as colour is more “directly” available? 我知道在第二种情况下会产生很多不必要的新字符串对象,但是由于颜色更“直接”可用,我是否会获得速度优势?

I would dare to make a third improvement: 我敢于进行第三次改进:

int sapphire = 0;
int ruby = 0;
int emerald = 0;

for(each box = i) {
    for(each gem = j) {
        String colour = i.getGem(j).getColour();
        if(“blue”.equals(colour)) sapphire++;
        else if(“red”.equals(colour)) ruby++;
        else if(“green”.equals(colour)) emerald++;
    }
}
  1. I use a local variable inside the for-loop. 我在for循环中使用局部变量。 Why? 为什么? Because you probably need it only there. 因为你可能只需要它。
  2. It is generally better to put STATIC_STRING.equals(POSSIBLE_NULL_VALUE). 通常最好放置STATIC_STRING.equals(POSSIBLE_NULL_VALUE)。

This has the advantage: easier to read and should have no performance problem. 这具有以下优点:更易于阅读且不存在性能问题。 If you have a performance problem, then you should consider looking somewhere else in your code. 如果您遇到性能问题,那么您应该考虑查看代码中的其他位置。 Related to this: this answer . 与此相关: 这个答案

conceptually both codes have equal complexity ie: O(i*j). 从概念上讲,两个代码具有相同的复杂性,即:O(i * j)。 But if calling a method and get a returned value are considered to be two processes then the complexity of your first code will be 4*O(i*j).(consider O(i*j) as a function) and of your second code will be O(i*(j+2)). 但是如果调用方法并获得返回值被认为是两个进程,那么第一个代码的复杂性将是4 * O(i * j)。(将O(i * j)视为函数)和第二个代码的复杂性代码为O(i *(j + 2))。 although this complexity difference is not considerable enough but if you are comparing then yes your first code is more complex and not a good programming style. 虽然这种复杂性差异不够大,但如果你比较那么肯定你的第一个代码更复杂而不是一个好的编程风格。

The cost of your string comparisons is going to wipe out all other considerations in this sort of approach. 字符串比较的成本将消除这种方法中的所有其他考虑因素。

You would be better off using something else (for example an enum ). 你会更好地使用其他东西(例如enum )。 That would also expand automatically. 那也会自动扩大。

(Although your for each loop isn't proper Java syntax anyway so that's a bit odd). (虽然你的每个循环都不是正确的Java语法,所以这有点奇怪)。

 enum GemColour {
     blue,
     red,
     green
 }

Then in your count function: 然后在你的计数功能:

 Map<GemColour, Integer> counts = new EnumMap<GemColour, Integer>(GemColour.class);

 for (Box b: box) {
    for (Gem g: box.getGems() {
       Integer count = counts.get(g.getColour());
       if (count == null) { 
          count=1;
       } else {
          count+=1;
       }

       counts.put(g.getColour(), count);
    }
 }

Now it will automatically extend to any new colors you add without you needing to make any code changes. 现在它将自动扩展到您添加的任何新颜色,而无需进行任何代码更改。 It will also be much faster as it does a single integer comparison rather than a string comparison and uses that to put the correct value into the correct place in the map (which behind the scenes is just an array). 它也会更快,因为它进行单个整数比较而不是字符串比较,并使用它将正确的值放入地图中的正确位置(在幕后只是一个数组)。

To get the counts just do, for example: 要获得计数,例如:

counts.get(GemColour.blue);

As has been pointed out in the comments the java Stream API would allow you to do all of this in one line: 正如评论中指出的那样,java Stream API允许您在一行中完成所有这些操作:

boxes.stream().map(Box::getGems).flatMap(Collection::stream).collect(groupingBy‌​‌​(Gem::getColour, counting()))

It's less easy to understand what it is doing that way though. 虽然这样做不太容易理解它在做什么。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Java方法调用比C ++中的虚方法调用更快? - Java method calls faster than virtual method calls in C++? 在java中随机选择对象调用常用方法的更好方法 - Better way to call common method on randomly selected object in java 什么方法更快? 线程或“单线方法” - Java - What is faster for the method? Thread or "oneline method" - Java 基于用户偏好的呼叫方法,更快/更好 - Call Method based on user preferences, which is faster/better java gui方法/对象调用 - java gui method/object calls 什么是在函数中更快地传递对象或静态调用它 - What is faster pass object in function or call it statically 在初始化对象或将其保存为变量并在其上调用方法时,调用方法是否更快 - Is it faster to call a method as I initialise an object or hold it as a variable and call the method on that 在Java中,从调用者或调用的方法中进行所有必要的检查是否更好? - Is it better in Java to make all necessary checks from the caller or in the method it calls? 如何更好地随机化 Java 中的方法调用(不重复类似的行)? - How to better randomize method calls in Java (without repeating similar lines)? 在java中编写异步调用序列的更好方法是什么? - What is the better way to code sequence of asynchronous calls in java?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM