Vb.net 哪个更快?拜瓦尔还是拜里夫?

Vb.net 哪个更快?拜瓦尔还是拜里夫?,vb.net,performance,byref,byval,Vb.net,Performance,Byref,Byval,在VB.NET中,哪个方法参数使用得更快,ByVal或ByRef 另外,在运行时(RAM)哪一个会消耗更多的资源 我通读了一遍,但答案不适用或不够具体。ByVal创建变量的副本,而ByRef传递指针。因此,我想说,ByVal速度较慢(由于复制需要时间),并且占用更多内存。这取决于具体情况。如果您正在传递对象,则该对象已经在传递指针。这就是为什么如果您传入一个ArrayList(例如),并且您的方法向ArrayList添加了一些东西,那么调用代码也将相同的对象传入了它的ArrayList,因为它

在VB.NET中,哪个方法参数使用得更快,
ByVal
ByRef

另外,在运行时(RAM)哪一个会消耗更多的资源



我通读了一遍,但答案不适用或不够具体。

ByVal
创建变量的副本,而
ByRef
传递指针。因此,我想说,
ByVal
速度较慢(由于复制需要时间),并且占用更多内存。

这取决于具体情况。如果您正在传递对象,则该对象已经在传递指针。这就是为什么如果您传入一个ArrayList(例如),并且您的方法向ArrayList添加了一些东西,那么调用代码也将相同的对象传入了它的ArrayList,因为它是相同的ArrayList。它唯一不传递指针的时间是将具有内在数据类型(如int或double)的变量传递到函数中时。此时,它将创建一个副本。但是,这些对象的数据量非常小,无论是在内存使用还是执行速度方面,都几乎没有什么区别。

Byval和ByRef参数的使用应该基于需求和它们如何工作的知识,而不是速度

回应Slough的评论-

哪个在运行时消耗更多资源?

参数在堆栈上传递。堆栈速度非常快,因为它的内存分配只是一个指针增量,以保留一个新的“帧”或“分配记录”。如果使用任何“堆栈”空间传递参数,大多数.NET参数都不会超过机器寄存器的大小。实际上,基本类型和指针都是在堆栈上分配的。NET中的堆栈大小限制为1MB。这应该让您了解通过参数传递消耗的资源有多少

您可能会发现这一系列文章很有趣:

哪个更快?ByVal或ByRef.

准确、准确地测量是很困难的,这取决于测量的环境,但我编写的一个基准测试调用了一个方法1亿次,得出了以下结论:

  • 引用类型-通过引用传递:420毫秒
  • 参考类型-通过值传递:382 ms
  • 值类型-通过引用传递:421毫秒
  • 值类型-通过值传递:416毫秒
注释每个方法中的变量和赋值-

  • 引用类型-通过引用传递:389毫秒
  • 参考类型-通过值传递:349 ms
  • 值类型-通过引用传递:416毫秒
  • 值类型-通过VAL传递:385毫秒
可以得出结论,通过val传递引用类型(字符串、类)将节省一些时间。您还可以说,通过ByVal传递值类型(整数、字节)将节省一些时间


同样,时间在事物的宏大计划中是微不足道的。更重要的是正确地使用ByVal和ByRef并理解“幕后”发生的事情。例程中实现的算法肯定会对程序的运行时间产生更多的影响。

如果您使用的是非常大的值类型(例如Guid非常大)通过引用传递参数可能会稍微快一点。在其他情况下,当您通过引用而不是通过值传递时,可能会有更多的复制等-例如,如果您有一个字节参数,那么一个字节显然比指针通过引用传递时所需的四个或八个字节要少

实际上,你几乎不应该担心这一点。编写尽可能可读的代码,这几乎总是意味着通过值而不是引用传递参数。我很少使用ByRef

如果您想提高性能并认为ByRef将帮助您,请在承诺之前仔细地(在您的具体情况下)对其进行基准测试


编辑:我在对另一个(以前接受,现在删除)答案的评论中注意到,对于ByRef和ByVal在值类型方面的含义,存在大量误解。我有一个多年来很流行的引用类型,它是C#术语,但同样的概念也适用于VB.NET。

如果您传递的是引用类型,ByRef会慢一些

这是因为传入的是指向指针的指针。对对象上字段的任何访问都需要取消引用一个额外的指针,这将需要几个额外的时钟周期才能完成

如果要传递值类型,那么如果结构具有多个成员,byref可能会更快,因为它只传递一个指针,而不是复制堆栈上的值。就访问成员而言,byref的速度会慢一些,因为它需要执行额外的指针解引用(sp->pValueType->member vs sp->member)

在VB中,大多数时候你不必担心这个问题

在.NET中,很少有具有大量成员的值类型。它们通常很小。在这种情况下,传入值类型与向过程传入多个参数没有什么不同。例如,如果有按值传入点对象的代码,则其性能将与以X和Y值作为参数的方法相同。看到DoSomething(x为整数,y为整数)可能不会引起性能问题。事实上,你可能永远不会三思而后行

如果您自己定义大值类型,那么您可能应该重新考虑将它们转换为引用类型

唯一的另一个区别是执行代码所需的指针间接寻址数量的增加。很少需要在该级别进行优化。 大多数情况下,要么存在可以解决的算法问题,要么性能瓶颈与IO有关,例如等待数据库或写入文件,在这种情况下,消除指针间接性对您没有多大帮助

所以,我建议你不要把重点放在byval或byref是否更快上,而应该真正做到f
Public Sub Method1(ByRef s As String)
    Dim c As String = s
End Sub

Public Sub Method2(ByVal s As String)
    Dim c As String = s
End Sub

Public Sub Method3(ByRef i As Integer)
    Dim x As Integer = i
End Sub

Public Sub Method4(ByVal i As Integer)
    Dim x As Integer = i
End Sub

Sub Main()

    Dim s As String = "Hello World!"
    Dim k As Integer = 5

    Dim t As New Stopwatch

    t.Reset()
    t.Start()
    For i As Integer = 0 To 100000000
        Method1(s)
    Next
    t.Stop()

    Console.WriteLine("Reference Type - ByRef " & t.ElapsedMilliseconds)

    t.Reset()
    t.Start()
    For i As Integer = 0 To 100000000
        Method2(s)
    Next
    t.Stop()

    Console.WriteLine("Reference Type - ByVal " & t.ElapsedMilliseconds)

    t.Reset()
    t.Start()
    For i As Integer = 0 To 100000000
        Method3(i)
    Next
    t.Stop()

    Console.WriteLine("Value Type - ByRef " & t.ElapsedMilliseconds)

    t.Reset()
    t.Start()
    For i As Integer = 0 To 100000000
        Method4(i)
    Next
    t.Stop()

    Console.WriteLine("Value Type - ByVal " & t.ElapsedMilliseconds)

    Console.ReadKey()

End Sub
Public Structure rStruct
    Public v1 As Integer
    Public v2 As String
End Structure

Public Class tClass
    Public v1 As Integer
    Public v2 As String
End Class



Public Sub Method1(ByRef s As String)
    Dim c As String = s
End Sub

Public Sub Method2(ByVal s As String)
    Dim c As String = s
End Sub

Public Sub Method3(ByRef i As Integer)
    Dim x As Integer = i
End Sub

Public Sub Method4(ByVal i As Integer)
    Dim x As Integer = i
End Sub

Public Sub Method5(ByVal st As rStruct)
    Dim x As rStruct = st
End Sub

Public Sub Method6(ByRef st As rStruct)
    Dim x As rStruct = st
End Sub


Public Sub Method7(ByVal cs As tClass)
    Dim x As tClass = cs
End Sub

Public Sub Method8(ByRef cs As tClass)
    Dim x As tClass = cs
End Sub
Sub DoTest()

    Dim s As String = "Hello World!"
    Dim cs As New tClass
    cs.v1 = 1
    cs.v2 = s
    Dim rt As New rStruct
    rt.v1 = 1
    rt.v2 = s
    Dim k As Integer = 5




    ListBox1.Items.Add("BEGIN")

    Dim t As New Stopwatch
    Dim gt As New Stopwatch

    If CheckBox1.Checked Then
        ListBox1.Items.Add("Using Garbage Collection")
        System.Runtime.GCSettings.LargeObjectHeapCompactionMode = System.Runtime.GCLargeObjectHeapCompactionMode.CompactOnce
        GC.Collect()
        GC.WaitForPendingFinalizers()
        GC.Collect()
        GC.GetTotalMemory(False)
    End If

    Dim d As Double = GC.GetTotalMemory(False)

    ListBox1.Items.Add("Free Memory:   " & d)

    gt.Start()
    t.Reset()
    t.Start()
    For i As Integer = 0 To 100000000
        Method1(s)
    Next
    t.Stop()

    ListBox1.Items.Add("Reference Type - ByRef " & t.ElapsedMilliseconds)

    t.Reset()
    t.Start()
    For i As Integer = 0 To 100000000
        Method2(s)
    Next
    t.Stop()

    ListBox1.Items.Add("Reference Type - ByVal " & t.ElapsedMilliseconds)

    t.Reset()
    t.Start()
    For i As Integer = 0 To 100000000
        Method3(i)
    Next
    t.Stop()

    ListBox1.Items.Add("Value Type - ByRef " & t.ElapsedMilliseconds)

    t.Reset()
    t.Start()
    For i As Integer = 0 To 100000000
        Method4(i)
    Next
    t.Stop()

    ListBox1.Items.Add("Value Type - ByVal " & t.ElapsedMilliseconds)

    t.Reset()
    t.Start()

    For i As Integer = 0 To 100000000
        Method5(rt)
    Next
    t.Stop()

    ListBox1.Items.Add("Structure Type - ByVal " & t.ElapsedMilliseconds)

    t.Reset()
    t.Start()

    For i As Integer = 0 To 100000000
        Method6(rt)
    Next
    t.Stop()

    ListBox1.Items.Add("Structure Type - ByRef " & t.ElapsedMilliseconds)

    t.Reset()
    t.Start()

    For i As Integer = 0 To 100000000
        Method7(cs)
    Next
    t.Stop()

    ListBox1.Items.Add("Class Type - ByVal " & t.ElapsedMilliseconds)

    t.Reset()
    t.Start()

    For i As Integer = 0 To 100000000
        Method8(cs)
    Next
    t.Stop()
    gt.Stop()

    ListBox1.Items.Add("Class Type - ByRef " & t.ElapsedMilliseconds)
    ListBox1.Items.Add("Total time " & gt.ElapsedMilliseconds)
    d = GC.GetTotalMemory(True) - d
    ListBox1.Items.Add("Total Memory Heap consuming (bytes)" & d)


    ListBox1.Items.Add("END")

End Sub


Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click


    DoTest()

End Sub