Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Immutable types and performances

Tags:

julia

I'm wondering about immutable types and performances in Julia.

  1. In which case does making a composite type immutable improve perfomances? The documentation says

    They are more efficient in some cases. Types like the Complex example above can be packed efficiently into arrays, and in some cases the compiler is able to avoid allocating immutable objects entirely.

    I don't really understand the second part.

  2. Are there cases where making a composite type immutable reduce performance (beyond the case where a field needs to be changed by reference)? I thought one example could be when an object of an immutable type is used repeatedly as an argument, since

    An object with an immutable type is passed around (both in assignment statements and in function calls) by copying, whereas a mutable type is passed around by reference.

    However, I can't find any difference in a simple example:

    abstract MyType
    
    type MyType1 <: MyType
        v::Vector{Int}
    end
    
    immutable MyType2 <: MyType
        v::Vector{Int}
    end
    
    
    g(x::MyType) = sum(x.v)
    
    function f(x::MyType)
        a = zero(Int)
        for i in 1:10_000
            a += g(x)
        end
        return a
    end
    
    x = fill(one(Int), 10_000)
    x1 = MyType1(x)
    @time f(x1)
    # elapsed time: 0.030698826 seconds (96 bytes allocated)
    x2 = MyType2(x)
    @time f(x2)
    # elapsed time: 0.031835494 seconds (96 bytes allocated)
    

    So why isn't f slower with an immutable type? Are there cases where using immutable types makes a code slower?

like image 263
Matthew Avatar asked Aug 02 '15 18:08

Matthew


People also ask

Does immutability affect performance?

The short answer is yes; it will hurt performance because you're only ever creating objects instead of mutating existing ones, resulting in more object creation overhead. However, the long answer is not really.

What are immutable types?

An immutable type, in the context of C#, is a type of object whose data cannot be changed after its creation. An immutable type sets the property or state of the object as read only because it cannot be modified after it is assigned during initialization.

What is immutable data type example?

Immutable Objects : These are of in-built types like int, float, bool, string, unicode, tuple. In simple words, an immutable object can't be changed after it is created.


2 Answers

Immutable types are especially fast when they are small and consist entirely of immediate data, with no references (pointers) to heap-allocated objects. For example, an immutable type that consists of two Ints can potentially be stored in registers and never exist in memory at all.

Knowing that a value won't change also helps us optimize code. For example you access x.v inside a loop, and since x.v will always refer to the same vector we can hoist the load for it outside the loop instead of re-loading on every iteration. However whether you get any benefit from that depends on whether that load was taking a significant fraction of the time in the loop.

It is rare in practice for immutables to slow down code, but there are two cases where it might happen. First, if you have a large immutable type (say 100 Ints) and do something like sorting an array of them where you need to move them around a lot, the extra copying might be slower than pointing to objects with references. Second, immutable objects are usually not allocated on the heap initially. If you need to store a heap reference to one (e.g. in an Any array), we need to move the object to the heap. From there the compiler is often not smart enough to re-use the heap-allocated version of the object, and so might copy it repeatedly. In such a case it would have been faster to just heap-allocate a single mutable object up front.

like image 100
Jeff Bezanson Avatar answered Oct 14 '22 06:10

Jeff Bezanson


This test includes a special cases, so is not extendable and could not reject better performance of immutable types.
check following test and look at different allocation times,when create a vector of immutables compare to a vector of mutables

abstract MyType
type MyType1 <: MyType
    i::Int
    b::Bool
    f::Float64
end
immutable MyType2 <: MyType
    i::Int
    b::Bool
    f::Float64
end

@time x=[MyType2(i,1,1) for i=1:100_000];
# => 0.001396 seconds (2 allocations: 1.526 MB)
@time x=[MyType1(i,1,1) for i=1:100_000];
# => 0.003683 seconds (100.00 k allocations: 3.433 MB)
like image 36
Reza Afzalan Avatar answered Oct 14 '22 05:10

Reza Afzalan