开发者

How efficient is it to return very large data in F#?

Suppose we have a Matrix class in F# and you overload the (+) operator. Then, we will have something like this:

type Matrix(n : int, m : int) = 
    ...
    static member (+) (A : Matrix, B : Matrix) = 
        let res = new Matrix(A.Dim1, A.Dim2) // suppose A and B have the same dimension
        ... // compute here the sum
        res

Comparing to C/C++, we would have something like this:

static const Matrix operator+(const Matrix& A, const Matrix& B)
{
    Matrix res(A.Dim1(), A.Dim2());
    ... // compute here the sum
    return res;
}

Now, observe that in F#, the matrix res is allocated in the heap memory, in contrast with the C++ version, that allocates res in the stack memory.

So far so good. Observe what happens when we want a "reference" to the result of the sum operation in both versions:

Matrix result = A + B; // deep copy in C++ (because res has to be destroyed after its return)

let result = A + B // shallow copy in F# (res was allocated in the heap memory)

Am I missing something here or the (+) operator in 开发者_高级运维F# ends up being more efficient than its counterpart in C/C++, because of the shallow and deep copy behavior?


Usually, it is faster to keep data on the stack. And commercial-grade C++ compilers will often use the "return value optimization".

But until you start to actually measure the performance, you will never know which is faster. There are too many factors involved.


.NET has reference and value types, and value types are allocated on the stack (unless they're part of a reference type, but let's not get carried away). In C# you would declare them with the class and struct keywords, respectively.

While this is not really part of the F# type declaration semantics, you can tell the compiler to create a particular type as a value type, by using the [<Struct>] attribute.


Yep, F# (as C# and VB.NET) passes objects (class instances) by reference (so no copies created), if you use structs (in C#, not sure if you can create such a thing in F#) then they are passed by value (thus copies are created). Note that in C++ you can do it both ways too. But, yes, the way you propose your example, the F# solution is going to be more efficient.

Alas, somebody would probably point out that if you make Matrix a mutable object then you'll be even more performant (as no new Matrix objects need to be created), but then you loose all of the goodness of immutability.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜