I come from a C background and I am use to creating variables and passing them into functions as arguments and keep passing them around if I want to be able to use them. Having them as global variable’s I am able to access them anywhere but the is frowned upon and much slower.
Now I am new in C#, but I noticed I don’t need to pass variables around because they can be “public” or “private” and I see this as a “global” variable and I would think it would be much slower?
Example 1.
public int test = 1;
public func1(int test){
test = 5;
func2(test);
}
Example 2.
public int test = 1;
public func1(){
test = 5;
func2();
}
Is there any benefit to passing variables through function arguments ( performance ), because I can easily access it anywhere. Right now I pass most my stuff around as function arguments because I am use to it.
C and C# are fairly different in terms of scoping since C# is an object oriented language. As far as I know, all variables must be encapsulated within a class in C#. Non-static variables used like this are called instance member variables. Instance member variables are not the same as global variables. Even in C++, which is a closer analogue, there’s a difference between member and global variables. The closest thing to global variables in C# are static variables. If those are made public, then they are globally accessable when accessed through a class instance or static class.
The slow down in C comes from how the variable is stored, I believe. Function parameters are copied from the stack to CPU registers, which have extremely fast read/write speeds. I don’t think there is much of a performance difference between the two in C#.
There are reasons to not use instance members and instead use function parameters. As a C programmer, I’m sure you’re familiar with passing by value and passing by pointer. In C#, types like primitives and structs are passed by value. Classes are effectively passed by pointer (reference). As such, there’s no real difference between passing a class into a function and accessing the class member. There is a differnence when passing structs or primitives–using the instance member is similar to passing by pointer (well, closer to reference, but that’s a C++ thing) as no copy is made on the stack. Passing them as parameters makes a local copy on the stack.
This has nothing to do with performance and everything to do with encapsulation. C# is an object oriented (oo) language, so we program things using classes and typically, we encourage class fields to be private. I know C can be written in a oo style but not everyone does that; what is your experience with oo?
Anyways, passing variables through function calls is a functional approach, though I find functional programming fits in with oo programming much better than sequential programming.
For your particular examples, there is negligible performance difference but there is a significant semantic difference. In order to compile, your field and method declaration will need to be in a class.
class MyClass
{
public int test = 1;
public func1(int test){
test = 5;
func2(test);
}
Example 2.
class MyClass
{
public int test = 1;
public func1(){
test = 5;
func2();
}
In the case of Example 1, func1 will be changing the value of a locally scoped variable called test. Once func1 exits, this variables will lose scope and its value will be lost.
In the case of Example2, func1 will be changing the value of the class scoped variable called test. Once func1 exits, the variable will live on with value 5.
If you had an external class inspecting this one’s field “test”, it would see very different effects depending on how you coded the method.
Performance wise, no. But there is a lot to gain in terms of maintainability.
Thank you for the two above answers, very much helped me understand more.
@HandOfPriam
Thank you for trying to explain it from C to C# it helped a lot.
@eisenpony
I meant to say in example1 I would pass in func1(test); the public variable.
So far in University my oo experience has been 1 java class ( that did not do a very good job at teaching oo concepts ), and my own time learning Unity for a few months. So yes I for sure have some gap in my knowledge in basic oo. But I have a very strong background in C.
It sounds like the general answer is to keep passing them through as function parameters.
My last question:
public int test = 1;
func1(test);
public void func1(int test){
int tempTest = test;
//big function with lots of calculations here that uses test around 50-100 times and numerous other variables, so I instead make a tempTest = test and use tempTest instead and pass tempTest to next function when I am done.
func2(tempTest);
}
This may be a weird question, but should I make it into a temp variable to keep it in the scope of the function so it doesnt have to go looking around for it (only now looks for the tempTest above) or would the int test passed into the function be the same scope..or possibly if I dont pass in int test as a function param it would be looking around for the instance member. Forgive me if this was another bad question lol.
The int test param to the function is considered local to the function because int, a primitive, is passed by value, as @HandOfPriam mentioned. So, storing a temp var for an int won’t gain you anything.
Ok thanks, and what about if I don`t pass any params into the function and just set a temp var (tempTest) for the public variable test? Or still the same result no gain?
When you pass a parameter into a function, it will be in scope for the duration of the function and out of scope after that. Generally, you can think of an argument like a local variable that is declared and set just before entering the method. The only weird thing about your example is that you chose to name the argument the same as the instance variable.
When you do that, the variable with shorter scope will take precedence, so test in your function is not the same as test in your class.
The fact that you then send the test variable into the function complicates things further because you now need to understand value types vs reference types. In your example, you use int, which is a value type. This means the value of the class field test is being copied onto the stack when you call func1. When you change value types, the change only lasts as long as the stack frame, so when func1 ends and the stack pops, you lose the changes.
This sounds like pretty low level stuff - I think you’re asking if this will move the value to a processor register so that the code doesn’t need to go into memory to work with it. Frankly, I can’t answer this because I don’t know enough about the CLR but, personally, I think you are over thinking things. You will not make a big impact on your performance in this way - focus on making your algorithms more effecient and use a profiler to find areas in code to fine tune. And besides, oo languages are designed specifically to abstract this kind of low level decision making away from the programmer. You will just end up fighting with the framework if you want to have such fine control over things.