Каковы побочные эффекты производительности определения функций внутри рекурсивной функции vs снаружи в F #

Если у вас есть рекурсивная функция, которая полагается на какую-то другую функцию, что является предпочтительным способом ее реализации?

1) вне рекурсивной функции

let doSomething n = ...
let rec doSomethingElse x =
    match x with
    | yourDone -> ...
    | yourNotDone -> doSomethingElse (doSomething x)

2) внутри рекурсивной функции

let rec doSomethingElse x =
    let doSomething n = ...
    match x with
    | yourDone -> ...
    | yourNotDone -> doSomethingElse (doSomething x)

3) инкапсулировать как внутри третьей функции

let doSomethingElse x =
    let doSomething n = ...
    let innerDoSomethingElse =
        match x with
        | yourDone -> ...
        | yourNotDone -> innerDoSomethingElse (doSomething x)

4) что-то еще лучше?

6
Зачем голосовать? Это кажется очень хорошим/разумным вопросом.
добавлено автор Daniel, источник

1 ответы

module Test =

    let f x = 
      let add a b = a + b //inner function
      add x 1

    let f2 x =
      let add a = a + x //inner function with capture, i.e., closure
      add x

    let outerAdd a b = a + b

    let f3 x =
      outerAdd x 1

Переведено на:

[CompilationMapping(SourceConstructFlags.Module)]
public static class Test {

    public static int f(int x) {
        FSharpFunc> add = new [email protected]();
        return FSharpFunc.InvokeFast(add, x, 1);
    }

    public static int f2(int x) {
        FSharpFunc add = new [email protected](x);
        return add.Invoke(x);
    }

    public static int f3(int x) {
        return outerAdd(x, 1);
    }

    [CompilationArgumentCounts(new int[] { 1, 1 })]
    public static int outerAdd(int a, int b) {
        return (a + b);
    }

    [Serializable]
    internal class [email protected] : OptimizedClosures.FSharpFunc {
        internal [email protected]() { }

        public override int Invoke(int a, int b) {
            return (a + b);
        }
    }

    [Serializable]
    internal class [email protected] : FSharpFunc {
        public int x;

        internal [email protected](int x) {
            this.x = x;
        }

        public override int Invoke(int a) {
            return (a + this.x);
        }
    }
}

Единственной дополнительной стоимостью для внутренней функции является новшество экземпляра FSharpFunc - кажется незначительным.

Если вы не чувствительны к производительности very , я бы пошел с областью, которая имеет наибольший смысл, то есть самый узкий охват.

5
добавлено
См. Последнее предложение. У меня нет времени, чтобы сравнить его, но я упомянул о единственной заметной разнице.
добавлено автор Daniel, источник
Ответ может быть выведен из ваших фрагментов, но вы действительно должны это описать.
добавлено автор Ramon Snir, источник
Создание FSharpFunc может повредить производительность для использования с большим кодом, но в большинстве случаев это не имеет значения.
добавлено автор Ramon Snir, источник
Microsoft Stack Jobs
Microsoft Stack Jobs
1 788 участник(ов)

Work & freelance only Microsoft Stack. Feed https://t.me/Microsoftstackjobsfeed Чат про F#: @Fsharp_chat Чат про C#: @CSharpChat Чат про Xamarin: @xamarin_russia Чат общения:@dotnettalks

F# Chat
F# Chat
835 участник(ов)

fsharplang.ru Правила: https://t.me/fsharp_chat/26609 Новости: @fsharp_news F# в Gitter: gitter.im/fsharplang_ru Поиск функций: @fsdnbot Флудилка: @fsharp_flood Вакансии: @microsoftstackjobs Ссылки: @reasonml_ru @pro_net

Microsoft Developer Community Chat
Microsoft Developer Community Chat
584 участник(ов)

Чат для разработчиков и системных администраторов Microsoft Developer Community. __________ Новостной канал: @msdevru __________ Баним за: оскорбления, мат, рекламу, флуд, флейм, спам, NSFW контент, а также большое количество оффтоп тем. @banofbot

F# Flood: Год комбинаторов
F# Flood: Год комбинаторов
110 участник(ов)

F# флудилка @Fsharp_chat - основной https://t.me/vshapenko_builders Билдеры Василия