Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is 'using' improving C# performances

It seems that in most cases the C# compiler could call Dispose() automatically. Like most cases of the using pattern look like:

public void SomeMethod()
{
    ...

    using (var foo = new Foo())
    {
        ...
    }

    // Foo isn't use after here (obviously).
    ...
}

Since foo isn't used (that's a very simple detection) and since its not provided as argument to another method (that's a supposition that applies to many use cases and can be extended), the compiler could automatically and immediately call Dispose() without the developper requiring to do it.

This means that in most cases the using is pretty useless if the compiler does some smart job. IDisposable seem low level enough to me to be taken in account by a compiler.

Now why isn't this done? Wouldn't that improve the performances (if the developpers are... dirty).

like image 480
Wernight Avatar asked Jun 17 '10 14:06

Wernight


People also ask

What is the importance of using C?

Generally, we use to call C as a middle level language. Because, the 'C' compiler combines the capabilities of an assembly language with the features of a high-level language. Therefore, it is best for writing both system software and business packages. 'C' Programs are efficient and fast.

Why C is used nowadays?

C is a general-purpose programming language and can efficiently work on enterprise applications, games, graphics, and applications requiring calculations, etc. C language has a rich library which provides a number of built-in functions. It also offers dynamic memory allocation.

Why is C language better?

It is fast The programs that you write in C compile and execute much faster than those written in other languages. This is because it does not have garbage collection and other such additional processing overheads. Hence, the language is faster as compared to most other programming languages.


1 Answers

A couple of points:

Calling Dispose does not increase performance. IDisposable is designed for scenarios where you are using limited and/or unmanaged resources that cannot be accounted for by the runtime.

There is no clear and obvious mechanism as to how the compiler could treat IDisposable objects in the code. What makes it a candidate for being disposed of automatically and what doesn't? If the instance is (or could) be exposed outside of the method? There's nothing to say that just because I pass an object to another function or class that I want it to be usable beyond the scope of the method

Consider, for example, a factory patter that takes a Stream and deserializes an instance of a class.

public class Foo
{
    public static Foo FromStream(System.IO.Stream stream) { ... }
}

And I call it:

Stream stream = new FileStream(path);

Foo foo = Foo.FromStream(stream);

Now, I may or may not want that Stream to be disposed of when the method exits. If Foo's factory reads all of the necessary data from the Stream and no longer needs it, then I would want it to be disposed of. If the Foo object has to hold on to the stream and use it over its lifetime, then I wouldn't want it to be disposed of.

Likewise, what about instances that are retrieved from something other than a constructor, like Control.CreateGraphics(). These instances could exist outside of the code, so the compiler wouldn't dispose of them automatically.

Giving the user control (and providing an idiom like the using block) makes the user's intention clear and makes it much easier to spot places where IDisposable instances are not being properly disposed of. If the compiler were to automatically dispose of some instances, then debugging would be that much more difficult as the developer had to decipher how the automatic disposal rules applied to each and every block of code that used an IDisposable object.

In the end, there are two reasons (by convention) for implementing IDisposable on a type.

  1. You are using an unmanaged resource (meaning you're making a P/Invoke call that returns something like a handle that must be released by a different P/Invoke call)
  2. Your type has instances of IDisposable that should be disposed of when this object's lifetime is over.

In the first case, all such types are supposed to implement a finalizer that calls Dispose and releases all unmanaged resources if the developer fails to do so (this is to prevent memory and handle leaks).

like image 115
Adam Robinson Avatar answered Oct 04 '22 15:10

Adam Robinson