Declare an object inside or outside a loop?

前端 未结 16 785
广开言路
广开言路 2020-12-07 17:15

Is there any performance penalty for the following code snippet?

for (int i=0; i

        
相关标签:
16条回答
  • 2020-12-07 18:14

    The answer depends partly on what the constructor does and what happens with the object after the loop, since that determines to a large extent how the code is optimized.

    If the object is large or complex, absolutely declare it outside the loop. Otherwise, the people telling you not to prematurely optimize are right.

    0 讨论(0)
  • 2020-12-07 18:14

    I've actually in front of me a code which looks like this:

    for (int i = offset; i < offset + length; i++) {
        char append = (char) (data[i] & 0xFF);
        buffer.append(append);
    }
    ...
    for (int i = offset; i < offset + length; i++) {
        char append = (char) (data[i] & 0xFF);
        buffer.append(append);
    }
    ...
    for (int i = offset; i < offset + length; i++) {
        char append = (char) (data[i] & 0xFF);
        buffer.append(append);
    }
    

    So, relying on compiler abilities, I can assume there would be only one stack allocation for i and one for append. Then everything would be fine except the duplicated code.

    As a side note, java applications are known to be slow. I never tried to do profiling in java but I guess the performance hit comes mostly from memory allocation management.

    0 讨论(0)
  • 2020-12-07 18:15

    To get at the heart of this question... [Note that non-JVM implementations may do things differently if allowed by the JLS...]

    First, keep in mind that the local variable "o" in the example is a pointer, not an actual object.

    All local variables are allocated on the runtime stack in 4-byte slots. doubles and longs require two slots; other primitives and pointers take one. (Even booleans take a full slot)

    A fixed runtime-stack size must be created for each method invocation. This size is determined by the maximum local variable "slots" needed at any given spot in the method.

    In the above example, both versions of the code require the same maximum number of local variables for the method.

    In both cases, the same bytecode will be generated, updating the same slot in the runtime stack.

    In other words, no performance penalty at all.

    HOWEVER, depending on the rest of the code in the method, the "declaration outside the loop" version might actually require a larger runtime stack allocation. For example, compare

    for (...) { Object o = ... }
    for (...) { Object o = ... }
    

    with

    Object o;
    for (...) {  /* loop 1 */ }
    for (...) { Object x =...; }
    

    In the first example, both loops require the same runtime stack allocation.

    In the second example, because "o" lives past the loop, "x" requires an additional runtime stack slot.

    Hope this helps, -- Scott

    0 讨论(0)
  • 2020-12-07 18:16

    When using multiple threads (if your doing 50+) then i found this to be a very effective way of handling ghost thread problems:

    Object one;
    Object two;
    Object three;
    Object four;
    Object five;
    try{
    for (int i=0; i<someValue; i++)
    {
    o = someList.get(i);
    o.doSomething;
    }
    }catch(e){
    e.printstacktrace
    }
    finally{
    one = null;
    two = null;
    three = null;
    four = null;
    five = null;
    System.gc();
    }
    
    0 讨论(0)
提交回复
热议问题