Frage

Lektüre Welche ist schneller?ByVal oder ByRef? Ich habe mich gefragt, ob die Kommentare dort tatsächlich zutreffen Strings in Sachen Leistung.Da Strings vor der Übergabe kopiert werden, ist es dann nicht viel effizienter (wenn der Aufgerufene keine Kopie des String-Kurses benötigt), Strings zu übergeben? ByRef?

Danke,
CFP.

Bearbeiten: Betrachten Sie diesen Code, der mich glauben ließ, dass eine Art Kopie im Gange war:

Sub Main()
    Dim ByValStr As String = "Hello World (ByVal)!"
    Dim ByRefStr As String = "Hello World (ByRef)!"

    fooval(ByValStr)
    fooref(ByRefStr)

    Console.WriteLine("ByVal: " & ByValStr)
    Console.WriteLine("ByRef: " & ByRefStr)

    Console.ReadLine()
End Sub


Sub fooval(ByVal Str As String)
    Str = "foobar"
End Sub

Sub fooref(ByRef Str As String)
    Str = "foobar"
End Sub

Es wird ausgegeben:

ByVal: Hello World (ByVal)!
ByRef: foobar
War es hilfreich?

Lösung

Saiten sind nicht vor der Weitergabe kopiert.Strings sind Referenztypen, auch wenn sie sich in gewisser Weise wie Werttypen verhalten.

Sie sollten das verwenden, was im Kontext Ihrer Anforderungen am sinnvollsten ist.(Und wenn Ihre Anforderungen so etwas wie „Es muss jede letzte Nanosekunde Leistung auf Kosten aller anderen Überlegungen herausgequetscht werden“ lauten, sollten Sie wahrscheinlich den Profiler herausholen, anstatt nach Stackoverflow zu fragen!)

Dies ist mit ziemlicher Sicherheit etwas, worüber Sie sich keine Sorgen machen müssen, und ich bezweifle, dass es jemals einen signifikanten Leistungsunterschied gibt.Die einzige Situation, in der ich eine Chance auf einen Unterschied sehe, wäre beim Überholen groß Werttypen.

Andere Tipps

Ich beschloss, dies selbst zu überprüfen, um eine „wissenschaftlichere“ Antwort zu erhalten.Sie sind gleich.Wenn ich den folgenden Code verwende, ist ByVal etwa 2 % langsamer als ByRef.Wenn ich sie jedoch vertausche, sodass ich ByRef vor ByVal messe, ist ByRef etwa 2 % langsamer.Was in diesem Fall also tatsächlich wichtiger ist als ByRef oder ByVal, ist die Reihenfolge, in der sie ausgeführt werden :)

Function CreateString()

    Dim i As Integer
    Dim str As String = ""

    For i = 1 To 10000
        str = str & "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    Next i

    Return str
End Function

Sub fooval(ByVal Str As String)
    Str = Str & "foobar"
End Sub

Sub fooref(ByRef Str As String)
    Str = Str & "foobar"
End Sub

Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    Dim str As String = CreateString()
    Dim stopWatch As New Stopwatch
    Dim i As Integer

    stopWatch.Start()
    For i = 1 To 1000
        fooval(str)
    Next i
    stopWatch.Stop()
    Dim valtime As Long = stopWatch.ElapsedMilliseconds

    stopWatch.Restart()
    For i = 1 To 1000
        fooref(str)
    Next i
    stopWatch.Stop()
    Dim reftime As Long = stopWatch.ElapsedMilliseconds

    MsgBox("Val took " & valtime & " milliseconds and Ref took " & reftime & " milliseconds")
End Sub

Um das Verhalten von Klassentypen, einschließlich Zeichenfolgen, zu verstehen, betrachten Sie alle Klassentypparameter, Variablen, Felder und Array-Elemente usw.als „Objekt-IDs“ enthalten.Wenn Foo ist eine Variable vom Typ string, die Aussage Foo = 12345.ToString(); erstellt eine neue Objekt-ID (hypothetisch Objekt-ID#197) und ein neues Objekt vom Typ string mit dieser ID, die die fünf Zeichen enthält "12345".Es wird dann gespeichert Object ID#197 in die Variable Foo.Wenn man eine Routine mit einem Nicht-Ref-Parameter aufruft param, und geht vorbei Foo dann dazu param wird eine lokale Variable sein Object ID #197.Die Aussage param += "6"; würde ein neues Objekt erstellen (z.B.Objekt-ID #521) vom Typ String, das die sechs Zeichen enthält "123456" und lagern Object ID #521 hinein param.Beachten Sie, dass Foo hält immer noch Object ID#197, und dieses Objekt enthält immer noch die fünfstellige Zeichenfolge "12345".

Wenn param war vorbeigegangen ref, dann die Aussage param += "6" hätte gespeichert Object ID #521 hinein Foo.Es hätte immer noch keine erkennbare Änderung an Objekt Nr. 197 verursacht, außer vielleicht, um es für die Garbage Collection geeignet zu machen (falls Foo der einzige Verweis auf Objekt Nr. 197 gewesen wäre, würde ein Überschreiben bedeuten, dass es nirgendwo im Universum mehr einen Verweis auf dieses Objekt gäbe).

Beachten Sie, dass es im Allgemeinen ziemlich einfach ist, über unveränderliche Klassentypen nachzudenken string, auch ohne an Objekt-IDs zu denken, da die einzige Möglichkeit, die durch eine String-Variable dargestellte Zeichenfolge zu ändern, darin besteht, dort eine andere Objekt-ID zu speichern.Beim Umgang mit veränderbaren Klassentypen ist es jedoch unerlässlich, in Objekt-IDs zu denken.Übergabe einer Variablen vom Klassentyp Car, nicht per Verweis, wäre gleichbedeutend damit, eine Fahrgestellnummer von einem Zettel auf einen anderen zu kopieren und den letztgenannten Zettel einigen Ladenmitarbeitern zu geben und sie zu bitten, etwas damit zu tun.Wenn das erste Papier ursprünglich ein rotes Auto mit der Fahrgestellnummer 15934 identifizierte, könnte das erste Papier, wenn die Arbeiter fertig waren, ein blaues Auto mit der Fahrgestellnummer 15934 identifizieren, aber es wäre dasselbe Auto.Nichts, was die Arbeiter mit dem Zettel, den sie bekamen, tun konnten, noch irgendetwas, was sie mit dem Auto machen konnten, änderte nichts an dem Auto, auf das sich das erste Papier bezog.Andererseits würde die Übergabe des Parameters als Referenz eher so aussehen, als würden die Werkstattmitarbeiter ein Stück Papier mit der darauf geschriebenen Fahrgestellnummer erhalten und das Papier von ihnen zurückbekommen, wenn sie fertig sind.Wenn die Arbeiter die Fahrgestellnummer streichen und eine andere schreiben könnten, dann könnte sich der Zettel bei der Rückgabe auf dasselbe Auto oder ein anderes Auto beziehen;Wenn es sich um ein anderes Auto handelt, kann es sein, dass das Auto, auf das es sich ursprünglich bezog, verändert wurde oder auch nicht, und das Auto, auf das sich das Papier letztendlich bezieht, kann irgendeine Ähnlichkeit mit dem Original aufweisen oder auch nicht.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top