Question

En lisant Lequel est plus vite?ByVal ou ByRef ? m'a fait me demander si les commentaires qui s'y trouvaient s'appliquaient à Strings en termes de performances.Puisque les chaînes sont copiées avant d'être transmises, n'est-il pas beaucoup plus efficace (si l'appelé n'a pas besoin d'une copie du cours de chaînes) de transmettre des chaînes ByRef?

Merci,
PCP.

Modifier: Considérez ce code, qui m'a fait penser qu'il y avait une sorte de copie en cours :

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

Il produit :

ByVal: Hello World (ByVal)!
ByRef: foobar
Était-ce utile?

La solution

Cordes ne sont pas copié avant d'être transmis.Les chaînes sont des types référence, même si elles se comportent un peu comme des types valeur.

Vous devez utiliser ce qui est le plus logique dans le contexte de vos besoins.(Et si vos exigences sont quelque chose comme "vous devez exploiter chaque dernière nanoseconde de performances au détriment de toutes les autres considérations", alors vous devriez probablement pirater le profileur plutôt que de demander sur stackoverflow !)

C'est presque certainement quelque chose dont vous n'avez pas à vous inquiéter, et je doute qu'il y ait jamais une différence de performances significative.La seule situation où je peux voir une chance de différence serait lors du dépassement grand types de valeur.

Autres conseils

J'ai décidé de vérifier cela par moi-même, pour obtenir une réponse plus "scientifique".Ce sont les mêmes.Si j'utilise le code ci-dessous, ByVal est environ 2% plus lent que ByRef.Si, toutefois, je les échange, de sorte que je chronomètre ByRef avant ByVal, alors ByRef est environ 2 % plus lent.Donc, ce qui compte plus que ByRef ou ByVal dans ce cas, c'est l'ordre dans lequel ils s'exécutent :)

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

Pour comprendre le comportement des types de classe, y compris les chaînes, tenez compte de tous les paramètres, variables, champs et éléments de tableau de type classe, etc.comme contenant des "identifiants d'objet".Si Foo est une variable de type string, la déclaration Foo = 12345.ToString(); créera un nouvel identifiant d'objet (hypothétiquement, l'ID d'objet n° 197) et créera un nouvel objet de type string avec cet identifiant, contenant les cinq caractères "12345".Il stockera alors Object ID#197 dans la variable Foo.Si on appelle une routine avec un paramètre non-ref param, et passe Foo à cela, alors param sera une variable locale contenant Object ID #197.La déclaration param += "6"; créerait un nouvel objet (par ex.ID d'objet #521), de type chaîne, contenant les six caractères "123456" et stocker Object ID #521 dans param.Noter que Foo tient toujours Object ID#197, et cet objet contient toujours la chaîne de cinq caractères "12345".

Si param avait été dépassé ref, alors la déclaration param += "6" aurait stocké Object ID #521 dans Foo.Cela n'aurait toujours pas provoqué de changement observable sur l'objet n° 197, sauf peut-être pour le rendre éligible au garbage collection (si Foo avait été la seule référence à l'objet n°197, l'écraser signifierait qu'il n'existerait plus aucune référence à cet objet nulle part dans l'univers).

Notez qu'il est généralement assez facile de raisonner sur des types de classes immuables comme string, même sans penser en termes d'ID d'objet, puisque la seule façon de modifier la séquence de caractères représentée par une variable chaîne est d'y stocker un ID d'objet différent.Cependant, penser en termes d'ID d'objet devient essentiel lorsqu'il s'agit de types de classes mutables.Passer une variable de type classe Car, et non par référence, équivaudrait à copier un VIN d'un bout de papier à un autre, et à remettre ce dernier bout de papier à certains employés du magasin et à leur demander d'en faire quelque chose.Si le premier document identifiait à l'origine une voiture rouge avec le VIN#15934, alors lorsque les travailleurs auraient terminé, le premier document pourrait identifier une voiture bleue avec le VIN#15934, mais ce serait la même voiture.Rien de ce que les travailleurs pouvaient faire avec le bout de papier qui leur était donné, ni rien de ce qu'ils pouvaient faire avec la voiture, ne changerait la voiture à laquelle le premier papier faisait référence.D'un autre côté, transmettre le paramètre par référence reviendrait davantage aux employés de l'atelier à recevoir un morceau de papier sur lequel le VIN est écrit et à récupérer le papier une fois qu'ils auront terminé.Si les travailleurs pouvaient rayer le NIV et en écrire un autre, alors lorsqu'ils rendraient le bout de papier, il pourrait faire référence à la même voiture ou à une autre voiture ;s'il fait référence à une voiture différente, la voiture à laquelle elle faisait initialement référence peut ou non avoir été modifiée, et la voiture à laquelle le document finit par faire référence peut ou non ressembler à l'original.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top