Vb.net 是否始终分配函数的默认返回变量?
我感兴趣的是如何实现与函数名相同的默认变量Vb.net 是否始终分配函数的默认返回变量?,vb.net,compiler-optimization,Vb.net,Compiler Optimization,我感兴趣的是如何实现与函数名相同的默认变量 即使我不使用,Sum是否始终分配?(参见案例1) 如果我选择另一个变量(Total在案例3中),是否使用它而不是Sum 在编译时,以下3个等效案例是否也等效?还是有些人比其他人优越 ' EQUIVALENT CASES ' CASE 1 Function Sum(a As Integer, b As Integer) As Integer Return a + b End Function ' CASE 2 Function Sum(a
- 即使我不使用,
是否始终分配?(参见案例1)Sum
- 如果我选择另一个变量(
在Total
中),是否使用它而不是案例3
Sum
' EQUIVALENT CASES
' CASE 1
Function Sum(a As Integer, b As Integer) As Integer
Return a + b
End Function
' CASE 2
Function Sum(a As Integer, b As Integer) As Integer
Sum = a + b
End Function
' CASE 3
Function Sum(a As Integer, b As Integer) As Integer
Dim Total As Integer
Total = a + b
Return Total
End Function
正如我在某处读到的,编译到32字节以下的函数是内联插入的。我想知道,在某些情况下,我是否会因为选择的符号而超过或低于极限。我不是VB.NET专家,但我确实知道一些关于C的知识。在C#中,这种代码是不允许的。您应该始终
返回一个值,否则代码将无法编译
我猜VB.NET通过类似于C#中这样的方式绕过了这一点:
它默认值为Sum
,在int
的情况下,该值为0
根据此逻辑,变量被分配,对于引用类型,这意味着将不进行分配,因为它们默认为null
看看IL:
.method public static int32 Test() cil managed
{
// Code size 3 (0x3)
.maxstack 1
.locals init ([0] int32 Test)
IL_0000: nop
IL_0001: ldloc.0
IL_0002: ret
} // end of method Module1::Test
通过此功能
:
Function Test() As Integer
End Function
您将看到init
,它初始化一个变量(分配它)和ldloc
,这是一个获取变量值的调用,因此必须分配它。我分别将您的函数重命名为Sum1、Sum2和Sum3,然后通过LinqPad运行它们。以下是生成的IL:
Sum1:
IL_0000: ldarg.1
IL_0001: ldarg.2
IL_0002: add.ovf
IL_0003: ret
Sum2:
IL_0000: ldarg.1
IL_0001: ldarg.2
IL_0002: add.ovf
IL_0003: stloc.0 // Sum2
IL_0004: ldloc.0 // Sum2
IL_0005: ret
Sum3:
IL_0000: ldarg.1
IL_0001: ldarg.2
IL_0002: add.ovf
IL_0003: stloc.1 // Total
IL_0004: ldloc.1 // Total
IL_0005: ret
似乎Sum2和Sum3产生相同的IL。Sum1似乎更有效,因为它将运算符的结果直接放在堆栈上。其他人必须将结果从堆栈中拉入局部变量,然后将其推回到堆栈中 我冒昧地猜测,编译器使所有这三个相同的东西。案例3可能会“浪费”创建变量的时间。我知道。这就是为什么我将这个问题标记为vb.net,而不仅仅是.net或c#。当答案只与c#有关时,我发表了评论。这就是我最初否决它的原因。如果我们能留在VB,我会很高兴,因为在这些情况下,C#和VB编译器的方法可能完全不同。此外,C#不支持情况2
。如果可以,请删除答案的C部分。他是以什么方式编译程序集的?在释放模式下?然后我很确定它们会被内联。@sloth:它不会删除它们,但最终可能还是一样的(案例3最值得怀疑)。@miroxlav但我今天了解到,一般来说,是否使用helper变量很重要。请不要从中得出错误的结论。使用helper变量只会影响可读性,而不会影响执行速度,因为它可能会从JIT编译器中删除。非常有趣的是,编译器没有对它们进行优化,尤其是案例2。我很高兴我总是使用案例1,节省那些纳秒P@Keith-此IL来自LinqPad。当VS在发布模式下编译或JITted时,它可能会按照您的建议进行优化。@Keith-它可能不仅与变量创建有关,还与内联有关。函数体是内联插入的还是有一个常规调用,将参数放在堆栈上等等……啊,好的。我认为LinqPad(从未使用过它)模仿VS的功能。谢谢
Sum1:
IL_0000: ldarg.1
IL_0001: ldarg.2
IL_0002: add.ovf
IL_0003: ret
Sum2:
IL_0000: ldarg.1
IL_0001: ldarg.2
IL_0002: add.ovf
IL_0003: stloc.0 // Sum2
IL_0004: ldloc.0 // Sum2
IL_0005: ret
Sum3:
IL_0000: ldarg.1
IL_0001: ldarg.2
IL_0002: add.ovf
IL_0003: stloc.1 // Total
IL_0004: ldloc.1 // Total
IL_0005: ret