Home > Net >  Saving vs not saving object instantiation in C#
Saving vs not saving object instantiation in C#

Time:11-11

Quick question. Suppose I do something like this in C#:

new HttpClient().GetAsync("www.google.com");

instead of doing something like:

HttpClient httpClient = new();
httpClient.GetAsync("www.google.com");

Does using the 1st method have any benefits over the second one (e.g., better memory usage)? If not, why?

This has been confusing me for some time.

CodePudding user response:

Not significantly, no. In the second case in an unoptimised build it will store your HttpClient object on the stack as a local variable, but an optimised (release in VS) build will eliminate this.

(But even if it did, I wouldn't deliberately change my coding style for a few bytes nowadays. Write code that's easier to understand and maintain rather than trying to shave off the odd tiny bit of performance.)

This does make one small difference in the generated IL, to my surprise: in case 1 the compiler calls GetAsync whereas in the second it callvirts it:

IL_000a:  call       instance class [mscorlib]System.Threading.Tasks.Task`1<class [System.Net.Http]System.Net.Http.HttpResponseMessage> [System.Net.Http]System.Net.Http.HttpClient::GetAsync(string)
IL_000a:  callvirt   instance class [mscorlib]System.Threading.Tasks.Task`1<class [System.Net.Http]System.Net.Http.HttpResponseMessage> [System.Net.Http]System.Net.Http.HttpClient::GetAsync(string)

I guess in the first case the compiler knows exactly what method it's calling on what class: in the second, it's allowing for the case where it's got an HttpClient subclass instead somehow. But how that could possibly happen I don't know. Again I don't think this is any significant runtime overhead, particularly for HTTP client setup which you'll do very rarely.

To experiment with this yourself you can e.g. compile some example code to a module and then inspect this with ildasm from a Developer Command Prompt

csc example.cs -o -r:System.Net.Http.dll -t:module
ildasm example.netmodule

All generated with an up-to-date VS2022.

  • Related