Search Unity

Ref and Out or normal assign?

Discussion in 'Scripting' started by Lancaster13, Mar 27, 2015.

  1. Lancaster13

    Lancaster13

    Joined:
    Dec 24, 2014
    Posts:
    25
    Hello Guys,

    I'm a student of C# and i have a question about the Method parameters. Is better to assign my parameters, through the reference and output, or assign normally my parameters, and use all the method to define the variable value? What is minus expensive for performance? Because, the Out and Ref , uses the memory location to define the value.

    Thanks
     
  2. BenZed

    BenZed

    Joined:
    May 29, 2014
    Posts:
    524
  3. vothka

    vothka

    Joined:
    Mar 27, 2015
    Posts:
    59
    the question is: do you want your method to be able to change the value of the parameter?

    if you do not use ref or out the method will create a copy of it for its own usage, so you are safe for sideeffects
    if you use ref(or out) your method will use the same (let's say) int as it accesses the same memory location.

    so using ref would safe you one 4 byte int on your stack memory as long as you are in this specific method

    long story short: i wouldn't mind the performance aspect but keep the main question in mind if your method should be able to change the int itself.


    main()
    {
    int a = 2;
    a = timesTwo(a); //obviously here ref would make sense
    validateInput(a); // wouldn't use ref here
    }

    int timesTwo(int _x)
    {
    return _x * 2;
    }

    void validateInput(int _x)
    {
    //do stuff
    }
     
    Last edited: Mar 27, 2015
  4. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,741
    Are you actually in a situation where it isn't just better to use a return, since even if you need to return multiple data types you can just return a struct.
     
  5. makeshiftwings

    makeshiftwings

    Joined:
    May 28, 2011
    Posts:
    3,350
    I'd say you should absolutely NEVER make something ref or out for "performance", it should only ever be ref or out if you actually want to pass a reference or make it an out parameter.
    Actually not really, because instead you would be passing a 4 byte ref pointer (or 8 bytes on a 64-bit machine). But yeah like you said, the real question should be whether you need to actually pass a ref or get an out value, not which one might save a byte or two on the stack.
     
    Kiwasi likes this.
  6. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Performance is not going to make one iota of difference. If this is a completed game with identified hot code loops. If the algorithms have been optimised. Then just maybe you might consider this type of hacky reference management. Maybe.

    Pre optimisation is the root of all evil.

    So never, ever use ref or out as an optimisation strategy.

    Alright, rant over, I can now talk about when to use ref and out. ref and out are used when you want to change the actual memory of the variables passed in. For value types this means you can change the actual value of the variable in the calling context. Under normal circumstances when you pass in an int the method gets a copy of it. It can do whatever it likes to the int, without breaking the outer method.

    For reference types you can change the actual place the reference is pointing. This means if you pass in an array reference, and then change where that array reference is pointing, the reference will be changed in the outer context as well. Normally you can do whatever you like, but with out or ret you can easily break the outer method.

    So in the majority of cases out and ref are bad. They break the modularity of your code. The inner method must know something about its calling method. The calling method must have an idea of the implementation of the inner method. Its generally messy. You can't go and rewrite a method without considering every place its called. You have a range of possible side effects, introducing potentially hard to spot bugs.

    This is why these modifiers are used so sparingly. This is also why you have to explicitly use out and ref in the parameters, the language forces you to acknowledge the potential issues every time you call the method. There are some specific use cases where they make sense. But unless you have a specific logic or code flow reason to use them do not touch ref or out.