Насколько эффективно возвращать очень большие данные в F #? - PullRequest
1 голос
/ 10 сентября 2010

Предположим, у нас есть класс Matrix в F #, и вы перегружаете оператор (+).Тогда у нас будет что-то вроде этого:

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

По сравнению с C / C ++ у нас будет что-то вроде этого:

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

Теперь обратите внимание, что в F # матрица res выделяется в куче памяти , в отличие от версии C ++, которая выделяет res в памяти стека .

Пока все хорошо.Обратите внимание, что происходит, когда мы хотим, чтобы « ссылка » на результат операции суммирования в обеих версиях:

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)

Я что-то здесь упустил или оператор (+) в F # заканчиваетсябыть более эффективным, чем его аналог в C / C ++, из-за мелкого и глубокого копирования?

Ответы [ 3 ]

3 голосов
/ 10 сентября 2010

Обычно быстрее хранить данные в стеке.И коммерческие компиляторы C ++ часто используют «оптимизацию возвращаемого значения» .

Но пока вы не начнете измерять производительность, вы никогда не узнаете, что быстрее.Здесь слишком много факторов.

2 голосов
/ 10 сентября 2010

.NET имеет ссылочные типы и типы значений, а типы значений выделяются в стеке (если только они не являются частью ссылочного типа, но давайте не будем увлекаться). В C # вы можете объявить их с ключевыми словами class и struct соответственно.

Хотя это на самом деле не является частью семантики объявления типа F #, вы можете указать компилятору создать определенный тип как тип значения, используя атрибут [<Struct>].

2 голосов
/ 10 сентября 2010

Да, F # (как C # и VB.NET) передает объекты (экземпляры классов) по ссылке (поэтому копии не создаются), если вы используете структуры (в C #, не уверены, что вы можете создать такую ​​вещь в F #), тогдаони передаются по значению (при этом создаются копии).Обратите внимание, что в C ++ вы можете сделать это и в обоих случаях.Но, да, то, как вы предлагаете свой пример, решение F # будет более эффективным.

Увы, кто-то, вероятно, скажет, что если вы сделаете Matrix изменчивым объектом, то вы будете еще более производительными(поскольку не нужно создавать новые объекты Matrix), но тогда вы теряете все достоинства неизменности.

...