C#本地函数与JavaScript嵌套函数有哪些区别?

3
在C#中,本地函数是这样的:
public int MyFunction(int parameter)
{
     int local = 6;
     return MyLocalFunction(4);

     // Local Function
     int MyLocalFunction(int localFunctionParameter) => 42;
}

在JavaScript中,嵌套函数是:
function MyFunction(parameter) {
    var local = 6;
    return MyNestedFunction(4);

    // Nested Function
    function MyNestedFunction(localFunctionParameter) {
        return 42;
    }
}

除了语法之外,它们之间是否存在任何性能差异?

1
https://ericlippert.com/2012/12/17/performance-rant/ - mjwills
我不知道如何在任何一种语言中制作秒表。即便如此,在某些情况下,有些事情总是比另一些事情更快。无论如何,这里的主要重点只是展示我发现有趣的差异。 - AustinWBryan
1个回答

3

C#和JavaScript处理嵌套/本地函数的方式不同。

以您的示例为例,C#将编译此代码:

public int MyFunction(int parameter)
{
    int local = 6;
    return MyLocalFunction(4);

    // Local Function
    int MyLocalFunction(int localFunctionParameter) => 42;
}

将以下代码:

public int MyFunction(int parameter)
{
    int num = 6;
    return <MyFunction>g__MyLocalFunction|0_0(4);
}

[CompilerGenerated]
internal static int <MyFunction>g__MyLocalFunction|0_0(int localFunctionParameter)
{
    return 42;
}

如你所见,<MyFunction>g__MyLocalFunction|0_0巧妙地不在MyFunction内部,而是在其所包含的类中。我认为这使它们在本质上与嵌套函数有很大的不同之处,不仅仅是名称上的区别。然而,它阻止了我们在父函数外部使用该局部函数,这实际上是最终目标。
JavaScript实际上在每次调用时都会重新创建函数实例,这对性能来说是不好的,也是不必要的。我找到了一种防止这种行为的方法。你可以将JavaScript示例重写为以下内容:
var MyFunction = (function(parameter) {

    return function(parameter) {
        var local = 6;
        MyNestedFunction(4);
    };

    function MyNestedFunction() {
        return 42;
    }
}());

对我而言,这种方式很笨拙,也不是我想要思考本地/嵌套函数的方式。语法没有C#那么直观。

本地函数由于最终会被移动到类外部,默认情况下不会被实例化两次,因此是两全其美的选择。它具有更自然的语法和更好的性能(即使只是稍微优于其他方式)。


我从StackOverflow的答案中发现了这一点。区别在于背后发生的事情。据说这样做可以使MyNestedFunction不会在每次调用MyFunction时都被创建,因此对性能更好。 - AustinWBryan
抱歉,我误读了。为自己辩护,是因为local放错了位置。=) (另外,您确定JavaScript引擎在函数不逃逸时从不优化它吗?) - Ry-
这确实是它所属的地方(你应该将它从外部函数中移除)。外部函数运行并且被丢弃。至于保持简洁:理想情况下,它只需要优化,您就不必进行任何操作。但也许并非如此。在JavaScript中,通常的做法是将它们都作为模块范围函数,并且不导出“本地函数”。 - Ry-
那么,如果它在外部函数之外,它会在哪里呢?我觉得这就打败了它的全部意义。你是说在 JavaScript 中嵌套函数并不常见吗?我从未喜欢过这个想法,直到我在 C# 中使用本地函数并看到吸引力。 - AustinWBryan
1
是的,我说JavaScript中不逃逸函数和不使用任何本地变量的嵌套函数并不常见。 - Ry-
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接