public class People
{
private string _name;
public string Name { get; set; }
public string SName;
public string LamName => _name;
public People(string s)
{
_name = s;
Name = s;
}
public string GetName1()
{
return _name;
}
public string GetName2()
{
return Name;
}
public void OnlyFunc()
{
}
}
class Program
{
int interCount = 100000000;
public void AsAttribute()
{
People people = new People("Wave");
Stopwatch stopwatch = Stopwatch.StartNew();
for (int i = 0; i < interCount; i)
{
object val = people.SName;
}
stopwatch.Stop();
Console.WriteLine("AsAttribute: {0}ms", stopwatch.ElapsedMilliseconds);
}
public void Directly()
{
People people = new People("Wave");
Stopwatch stopwatch = Stopwatch.StartNew();
for (int i = 0; i < interCount; i )
{
object value = people.Name;
}
stopwatch.Stop();
Console.WriteLine("Directly: {0}ms", stopwatch.ElapsedMilliseconds);
}
public void UseFunc1()
{
People people = new People("Wave");
Stopwatch stopwatch = Stopwatch.StartNew();
for (int i = 0; i < interCount; i )
{
object value = people.GetName1();
}
stopwatch.Stop();
Console.WriteLine("UseFunc1: {0}ms", stopwatch.ElapsedMilliseconds);
}
public void UseFunc2()
{
People people = new People("Wave");
Stopwatch stopwatch = Stopwatch.StartNew();
for (int i = 0; i < interCount; i )
{
object value = people.GetName2();
}
stopwatch.Stop();
Console.WriteLine("UseFunc2: {0}ms", stopwatch.ElapsedMilliseconds);
}
public void Lambda()
{
People people = new People("Wave");
Stopwatch stopwatch = Stopwatch.StartNew();
for (int i = 0; i < interCount; i )
{
object value = people.LamName;
}
stopwatch.Stop();
Console.WriteLine("Lambda: {0}ms", stopwatch.ElapsedMilliseconds);
}
static void Main(string[] args)
{
Program p = new Program();
p.AsAttribute();
p.Directly();
p.Lambda();
p.UseFunc1();
p.UseFunc2();
}
}
This is the example of my test, and I get the result of time cost like:
AsAttribute: 82ms
Directly: 213ms
Lambda: 229ms
UseFunc1: 255ms
UseFunc2: 418ms
I'm wondering what cause the difference that when I mark it as an attribute, it gets the best performance, when I get the attribute using a lambda expression or a function, the performance falls down.
CodePudding user response:
As you can see from the code The first run is a field run, not an attribute. (So it's the fastest. You can know by looking at the code on the IL.) And directly is the direct execution of the property. A Lambda expression is equivalent to get {return ...} , so there will be no difference from Directly. UseFunc1 is slow by calling the method. UseFunc2 is the slowest because it executes two steps like mehtod --> property.
this is il code about your c# code
private string _name;
[CompilerGenerated]
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private string <Name>k__BackingField;
public string SName;
public string Name
{
[CompilerGenerated]
get
{
return <Name>k__BackingField;
}
[CompilerGenerated]
set
{
<Name>k__BackingField = value;
}
}
public string LamName
{
get
{
return _name;
}
}
public People(string s)
{
_name = s;
Name = s;
}
public string GetName1()
{
return _name;
}
public string GetName2()
{
return Name;
}
CodePudding user response:
The compiled code has already been supplied in another response. But one thing I’d like to touch on is what you called the “lamda” expression.
The “lamda” expression in your code is just an unfortunate monicker that looks the same as a lamda expression. It’s simply a shorthand way to define a single statement. It’s called an “expression-bodied member” which was introduced in C#6. It’s purely syntactic sugar, as they say, and compiles into the same code as the longer version. Here’s the Microsoft documentation for further reading.
So your LamName
is nothing more than shorthand for:
public string LamName
{
get;
}
You can even use them to perform these single statements as well:
public string AName
{
get => _name;
set => _name = value;
}
Methods incur an overhead when called. That’s because the current method state has to be pushed to the stack, and the new method called.
A property is “essentially” a method, and incurs the same type of overhead as a method call.
So, knowing the information above, you can start to see why GetName2
is almost double the length of time of GetName1
, as it’s “essentially” calling two methods instead of one (a method and a property to be exact).
The Name
and LamName
properties compile to the same code, so will perform the same, but only Name
can be set
.
And then obviously calling the SName
field directly will be the fastest.