Make sure it's initialized!





  • @blakeyrat said:



  • @Sutherlands said:

    Wow, you sure think you know a lot about me.  I'm the one who got the team to stop doing that.  I also suggested when I was on the team before that to use consts and inline functions instead of #DEFINEs (in C++).  What you apparently fail to grasp is not everyone is in the position of power that you have with your 30 years experience, or whatever it is.  Some of us don't have the power to say "you won't be doing it anymore" and instead are in the position where people tell me (this actually happened) "that's how we do it.  Give it a few months and then if you want to start making suggestions we'll talk about them."  But thanks for the advice, I'll be sure to listen to it... well, never, because I already do what I can do improve the practices of my team.

    I do not know anything about you (except from that wou have posted here), and I can not concieve of a reason for you to think otherwise. You are correct that "Some of us don't have the power to say "you won't be doing it anymore"", in fact, I would think that most do not. I am indeed fortunate that I own the company where I do [and this has very little to do with how much experience I have today, as I formed the company when I only had about 8 years of professional experience].

    But, everyone does have the power to say "I will not be doing that" (unless an indentured person on some third world country) Yes there will be ramifications, especially in todays market, but it comes down to a persons beliefs and ethics. I am not saying that everyone "should" take such a position, simply that it is their choice.


  • Discourse touched me in a no-no place

    @morbiuswilters said:

    That's a double negative.



  • @Sutherlands said:

    try

    {

      using(RecordSet rs = new RecordSet)

      {

        //Do stuff

      }

    }

    catch(Exception)

    {

      //Who cares? It's an example.

    }

     

    Hey look, i managed to dispose it without declaring it outside the try.

    Not sure what you are trying to prove here. "using" is nothing but syntactic sugar and in IL your code is equivalent to

    try
    {
      RecordSet rs = new RecordSet;
      try {
        //Do stuff
      }
      finally {
        rs.Dispose();
      }
    

    }
    catch(Exception)
    {

    //Who cares? It's an example.
    }

    So your still have declared your recordset outside the try block that handles the dispose. Only you have introduced 2 try blocks now.



  • @TheCPUWizard said:

    @morbiuswilters said:
    @boomzilla said:
    The time drag is calling the constructor to allocate and initialize a new instance, not the storage space for x itself. That is presumably something just sitting around on the stack (or equivalent).

    Does C# store objects on the stack under certain conditions? Because, last time I checked, Java always stores them on the heap. Anyway, in Java it's definitely going to grab more memory on the heap every time you call new MyBigObject(); Eventually the GC will kick in to keep you from running out of heap, though.


    .NET (in current impementation and all previous) strores Reference Types on the Heap, Value Types and the items that HOLD the reference are stored "in the context of their containing scope". So local valuetypes and reference type variable ar on eht stack.

    Yes, that was my point. Basically that the reference (probably a pointer, of course, but that's just an implementation detail) held by x will be on the stack. The "storage space for x" was just the reference. Obviously, value type stuff (in languages that have that sort of thing) will complicate matters, but is out of scope of this particular conversation.



  • @blakeyrat said:


    +1



  • @PJH said:

    @morbiuswilters said:
    That's a double negative.


    I don't get it, unless yo are counting the "n" and the"t" separately because there's an apostrophe between them...



  • @rstinejr said:

    @PJH said:
    @morbiuswilters said:
    That's a double negative.

    I don't get it, unless yo are counting the "n" and the"t" separately because there's an apostrophe between them...

    I suppose that might make sense if you were red-white colorblind.



  • @boomzilla said:

    @rstinejr said:
    @PJH said:
    @morbiuswilters said:
    That's a double negative.

    I don't get it, unless yo are counting the "n" and the"t" separately because there's an apostrophe between them...

    I suppose that might make sense if you were red-white colorblind.


    Red?

    D'oh!


  • Discourse touched me in a no-no place

    @rstinejr said:

    @PJH said:
    @morbiuswilters said:
    That's a double negative.

    I don't get it, unless yo are counting the "n" and the"t" separately because there's an apostrophe between them...

    The message says 'Don't Blindly Follow Convention.'



    The red circle with diagonal stripe indicates 'don't' or 'no' making the message "Don't, Don't Blindly Follow Convention."



    Which simplified translates as the sign saying "Blindly Follow Convention."



  • @PJH said:

    @morbiuswilters said:
    That's a double negative.

    "Hey, Ringo, that was the joke!"



  • @Sutherlands said:

    @KattMan said:

    Yes using will dispose, but what if it is the variable you are returning? 

    using(var x = new object())

    {

      return x;

    }

    <

    Not only will that not compile (System.Object does not have a Dispose method), but writing code like this is justifcation to break out the stabbings at my place of work.



  • @bjolling said:

    So your still have declared your recordset outside the try block that handles the dispose. Only you have introduced 2 try blocks now.

    No, I haven't.  I wrote a using block and correctly used it to clean up the resources of the recordset while making the code easy to read.  I don't give a flying crap what the IL does, or whether it's the same as what you wrote.  It was stated "you will need to declare the record set before the try in order to reference it in the finally in order to dispose."  I showed that, no, you don't, and I wrote code that did it the correct way.  Are you dense?



  • @pkmnfrk said:

    @Sutherlands said:

    @KattMan said:

    Yes using will dispose, but what if it is the variable you are returning? 

    using(var x = new object())

    {

      return x;

    }

    like this is justifcation to break out the stabbings at my place of work.

    Quoting fail.  I'm not sure what you're saying, exactly, but you make me look at it and say "this isn't even a valid scenario, since it will dispose of the object and you won't be able to use it."



  • @Sutherlands said:

    Quoting fail.

    Right, my post goes on the outside of the quote tags. Let's pretend it looked something like this:

    @Sutherlands said:

    @pkmnfrk said:

    @Sutherlands said:

    @KattMan said:

    Yes using will dispose, but what if it is the variable you are returning? 

    using(var x = new object())

    {

      return x;

    }

    Not only will this not compile (System.Object doesn't have a Dispose method), but writing code like this is justifcation to break out the stabbings at my place of work.

    I'm not sure what you're saying, exactly, but you make me look at it and say "this isn't even a valid scenario, since it will dispose of the object and you won't be able to use it."

    It's a perfectly valid scenario, from the compiler's point of view. The compiler will happily ensure that Dispose is called on the object just before it gets returned. If you need to return IDisposable objects, you don't put them in using blocks.



  • @PJH said:

    @morbiuswilters said:
    That's a double negative.

    Shit. Okay, here:



  • @pkmnfrk said:

    If you need to return IDisposable objects, you don't put them in using blocks.

    Right, so you wouldn't have to declare them outside whatever try/catch you have, because you wouldn't be disposing of them.



  • @Sutherlands said:

    Quoting fail.  I'm not sure what you're saying, exactly, but you make me look at it and say "this isn't even a valid scenario, since it will dispose of the object and you won't be able to use it."

    Disposing can object is nothing more than calling a method on that object. There is nothing inherent in this that means " you won't be able to use it", unless the developer of the class in question has explicitly coded in functionallity to detect the call to Dispose and do something special.



  • @TheCPUWizard said:

    @Sutherlands said:

    Quoting fail.  I'm not sure what you're saying, exactly, but you make me look at it and say "this isn't even a valid scenario, since it will dispose of the object and you won't be able to use it."

    Disposing can object is nothing more than calling a method on that object. There is nothing inherent in this that means " you won't be able to use it", unless the developer of the class in question has explicitly coded in functionallity to detect the call to Dispose and do something special.

    I understand what you're saying, but I would think that the vast majority of IDisposable objects cannot be used, or are not in a valid state, after they are disposed.  So it may be valid code in very specific circumstances.



  • @TheCPUWizard said:

    @Sutherlands said:

    Quoting fail.  I'm not sure what you're saying, exactly, but you make me look at it and say "this isn't even a valid scenario, since it will dispose of the object and you won't be able to use it."

    Disposing can object is nothing more than calling a method on that object. There is nothing inherent in this that means " you won't be able to use it", unless the developer of the class in question has explicitly coded in functionallity to detect the call to Dispose and do something special.

    ...which is the exact semantics that IDisposable demands. If you call Dispose() on, say, a Stream, then calling any of its instance methods will cause an ObjectDisposedException to be thrown. If an object doesn't have any special dispose logic, then it shouldn't even have a Dispose() method.

    To paraphase Blakeyrat, this shit isn't hard people.



  • @pkmnfrk said:

    @TheCPUWizard said:

    @Sutherlands said:

    Quoting fail.  I'm not sure what you're saying, exactly, but you make me look at it and say "this isn't even a valid scenario, since it will dispose of the object and you won't be able to use it."

    Disposing can object is nothing more than calling a method on that object. There is nothing inherent in this that means " you won't be able to use it", unless the developer of the class in question has explicitly coded in functionallity to detect the call to Dispose and do something special.

    ...which is the exact semantics that IDisposable demands. If you call Dispose() on, say, a Stream, then calling any of its instance methods will cause an ObjectDisposedException to be thrown. If an object doesn't have any special dispose logic, then it shouldn't even have a Dispose() method.

    To paraphase Blakeyrrequat, this shit isn't hard people.

    There is nothing that demands those Semantics. The only requirement (in this respect) is that Dispose "releases valuable resources". An object is free to re-create these resources, and many objects (including BCL objects) maintain some properties that are valid even after Dispose.

    This is one of the reasons why so many people consider the Disposable Pattern fatally flawed.



  • @Sutherlands said:

    @bjolling said:

    So your still have declared your recordset outside the try block that handles the dispose. Only you have introduced 2 try blocks now.

    ... I don't give a flying crap what the IL does, or whether it's the same as what you wrote.... Are you dense?

    You sure sound like a competent programmer. I'd rather be called dense than spouting that kind of crap.



  • @bjolling said:

    @Sutherlands said:

    @bjolling said:

    So your still have declared your recordset outside the try block that handles the dispose. Only you have introduced 2 try blocks now.

    ... I don't give a flying crap what the IL does, or whether it's the same as what you wrote.... Are you dense?
    You sure sound like a competent programmer. I'd rather be called dense than spouting that kind of crap.

    Ah, taking a quote out of context and then deriding someone for it.  Good job!



  • @Sutherlands said:

    @bjolling said:

    @Sutherlands said:

    @bjolling said:

    So your still have declared your recordset outside the try block that handles the dispose. Only you have introduced 2 try blocks now.

    ... I don't give a flying crap what the IL does, or whether it's the same as what you wrote.... Are you dense?
    You sure sound like a competent programmer. I'd rather be called dense than spouting that kind of crap.
    Ah, taking a quote out of context and then deriding someone for it.  Good job!

    Thanks. At least it's better than claiming that you don't need to care about the IL that your code generates. But seriously, what important part of your quote did I leave out? I was specifically responding to the "I don't care what the IL does" part

     



  • @bjolling said:

    @Sutherlands said:

    @bjolling said:

    @Sutherlands said:

    @bjolling said:

    So your still have declared your recordset outside the try block that handles the dispose. Only you have introduced 2 try blocks now.

    ... I don't give a flying crap what the IL does, or whether it's the same as what you wrote.... Are you dense?
    You sure sound like a competent programmer. I'd rather be called dense than spouting that kind of crap.
    Ah, taking a quote out of context and then deriding someone for it.  Good job!
    Thanks. At least it's better than claiming that you don't need to care about the IL that your code generates. But seriously, what important part of your quote did I leave out? I was specifically responding to the "I don't care what the IL does" part

     

    I think that safely qualifies as "trivia most developers don't need to know".



  • @morbiuswilters said:

    @bjolling said:

    @Sutherlands said:

    @bjolling said:

    @Sutherlands said:

    @bjolling said:

    So your still have declared your recordset outside the try block that handles the dispose. Only you have introduced 2 try blocks now.

    ... I don't give a flying crap what the IL does, or whether it's the same as what you wrote.... Are you dense?

    You sure sound like a competent programmer. I'd rather be called dense than spouting that kind of crap.
    Ah, taking a quote out of context and then deriding someone for it.  Good job!
    Thanks. At least it's better than claiming that you don't need to care about the IL that your ode generates. But seriously, what important part of your quote did I leave out? I was specifically responding to the "I don't care what the IL does" part

    I think that safely qualifies as "trivia most developers don't need to know".

    I disagree. I have full expectations that any "non Junior" is familiar with key elements of IL. It comprises about 10%-15% of my screening [enough to matter, but not enough to "fail" if everything else is excelllent]



  • @TheCPUWizard said:

    @morbiuswilters said:
    @bjolling said:

    @Sutherlands said:

    @bjolling said:

    @Sutherlands said:

    @bjolling said:

    So your still have declared your recordset outside the try block that handles the dispose. Only you have introduced 2 try blocks now.

    ... I don't give a flying crap what the IL does, or whether it's the same as what you wrote.... Are you dense?

    You sure sound like a competent programmer. I'd rather be called dense than spouting that kind of crap.
    Ah, taking a quote out of context and then deriding someone for it.  Good job!
    Thanks. At least it's better than claiming that you don't need to care about the IL that your ode generates. But seriously, what important part of your quote did I leave out? I was specifically responding to the "I don't care what the IL does" part

    I think that safely qualifies as "trivia most developers don't need to know".

    I disagree. I have full expectations that any "non Junior" is familiar with key elements of IL. It comprises about 10%-15% of my screening [enough to matter, but not enough to "fail" if everything else is excelllent]

    Maybe it's really different in .NET, but "internals of the JVM/other runtime" are something 95% of developers never need to know (and most of them don't).



  • @TheCPUWizard said:

    @pkmnfrk said:
    @TheCPUWizard said:

    @Sutherlands said:

    Quoting fail.  I'm not sure what you're saying, exactly, but you make me look at it and say "this isn't even a valid scenario, since it will dispose of the object and you won't be able to use it."

    Disposing can object is nothing more than calling a method on that object. There is nothing inherent in this that means " you won't be able to use it", unless the developer of the class in question has explicitly coded in functionallity to detect the call to Dispose and do something special.

    ...which is the exact semantics that IDisposable demands. If you call Dispose() on, say, a Stream, then calling any of its instance methods will cause an ObjectDisposedException to be thrown. If an object doesn't have any special dispose logic, then it shouldn't even have a Dispose() method.

    To paraphase Blakeyrrequat, this shit isn't hard people.

    There is nothing that demands those Semantics. The only requirement (in this respect) is that Dispose "releases valuable resources". An object is free to re-create these resources, and many objects (including BCL objects) maintain some properties that are valid even after Dispose.

    This is one of the reasons why so many people consider the Disposable Pattern fatally flawed.

    Are you arguing that it actually makes sense to return disposed objects, or is this just pedantic dickweedery?

    Edit: I re-read the thread again and there were a lot less posts talking about returning from inside a using than I remember. So, uh, nevermind.



  • @bjolling said:

    I was specifically responding to the "I don't care what the IL does" part

    Let me summarize the conversation for you.

    KattMan: "You need to declare the record set[sic] before the try in order to ... dispose."

    Sutherlands: No you don't, here's code

    bjolling: using is syntatic sugar.  The IL is the same as <>. (therefore) You have declared your recordset outside of a try.

    Sutherlands: I don't care if the IL is the same, I didn't declare a recordset outside of a try.

    bjolling: OMG YOU DON'T CARE ABOUT IL.

     

    No... that's not what I said.  You can't take code, say "that's the same IL as this code!" and then claim that I wrote something (a variable declaration outside of a try) that I didn't.  I never made a blanket statement that I don't care about IL.  After your fail, I even reiterated what the point of my code was.



  • @Sutherlands said:

    @bjolling said:

    I was specifically responding to the "I don't care what the IL does" part

    Let me summarize the conversation for you.

    KattMan: "You need to declare the record set[sic] before the try in order to ... dispose."

    Sutherlands: No you don't, here's code

    bjolling: using is syntatic sugar.  The IL is the same as <>. (therefore) You have declared your recordset outside of a try.

    Sutherlands: I don't care if the IL is the same, I didn't declare a recordset outside of a try.

    bjolling: OMG you claim YOU DON'T CARE ABOUT IL.

     

    No... that's not what I said.  You can't take code, say "that's the same IL as this code!" and then claim that I wrote something (a variable declaration outside of a try) that I didn't.  I never made a blanket statement that I don't care about IL.  After your fail, I even reiterated what the point of my code was.

    minor FTFY

    It's like you are proud you can do addition without using "plus" after discovering that 5 minus (-1) equals 6 and then calling me dense for telling you that in the background it is still an addition

     



  • @morbiuswilters said:

    @TheCPUWizard said:
    @morbiuswilters said:
    @bjolling said:

    ..snip..

    I think that safely qualifies as "trivia most developers don't need to know".

    I disagree. I have full expectations that any "non Junior" is familiar with key elements of IL. It comprises about 10%-15% of my screening [enough to matter, but not enough to "fail" if everything else is excelllent]

    Maybe it's really different in .NET, but "internals of the JVM/other runtime" are something 95% of developers never need to know (and most of them don't).

    Actually I have to agree with Morbs. If you just strive to be a compentent programmer or developer, it really is just a triva. It only starts becoming important if you have the ambition to become technical project lead or software architect. Only then things like garbage collection and other run-time stuff start coming into the picture.

    I once had a really bad interviewing experience when applying for a junior/medior .NET role where the interviewer kept pounding me with questions like second generation and garbage collection until I literally stopped caring about getting the position

     



  • @bjolling said:

    It's like you are proud you can do addition without using "plus" after discovering that 5 minus (-1) equals 6 and then calling me dense for telling you that in the background it is still an addition

    No, it's like I am proud that I can write good code and then calling you dense for telling me that it generates the same IL as bad code.



  • @bjolling said:

    It's like you are proud you can do subtraction by writing 5-1 and then calling me dense for telling you that in the background it is still doing an addition of a negative number.

    You know what, I take it back, it's a decent analogy, you just got some things mixed up.  I FTFY.



  • @bjolling said:

    @morbiuswilters said:

    @TheCPUWizard said:
    @morbiuswilters said:
    @bjolling said:

    ..snip..

    I think that safely qualifies as "trivia most developers don't need to know".

    I disagree. I have full expectations that any "non Junior" is familiar with key elements of IL. It comprises about 10%-15% of my screening [enough to matter, but not enough to "fail" if everything else is excelllent]

    Maybe it's really different in .NET, but "internals of the JVM/other runtime" are something 95% of developers never need to know (and most of them don't).

    Actually I have to agree with Morbs. If you just strive to be a compentent programmer or developer, it really is just a triva. It only starts becoming important if you have the ambition to become technical project lead or software architect. Only then things like garbage collection and other run-time stuff start coming into the picture.

    I once had a really bad interviewing experience when applying for a junior/medior .NET role where the interviewer kept pounding me with questions like second generation and garbage collection until I literally stopped caring about getting the position

    I thuink it is largely based on what one considers "Junior". 

    I DEFINATELY expect someone to be able to draw a diagram of what happens in memory during each of the GC phases for each generation and for each GV type - unless they are applying for a position with "under one year of .NET experience".

    In my environments, one remains in the "Junior" status until around 3-5 years of experience (and this presumes a well rounded experience, not 5 years of doing webforms,or any other single technology. Then one is in the "Regular"/"MidLevel" until they have a good understanding of the entire environment (not knowing it off the top of their head, but at least being able to have a starting point, knowing where to go for the authoritative answer, and judging if that answer is reasonable). This usually takes  another 3-5 years, and requires the person actually be in an environment that uses these advanced capabilities.

    I realize there are lots of situations where what I consider "Junior" is accepable for most of the staff, but that is not the environment I have typically worked in for many years (decades)..

    As a concerete example, last week we had a situation where a bad object (not desired state) object was being passed into a third party library. It is a realtime system, so adding breakpoints would not work. Since it was third party, adding diagnostic statements was not practical either.

    The quickest solution was to assign one of my developers to intercept the load of the assembly, use reflection to find all methods that tooks this specific type as a parameter, and IL-REWRITE the methods to invoke a custom hook that could check the state. It took him about 20 minutes to write and test, and we found the problem within 10 minutes.

    In this case the technique was pretty much necessary, in other scenarios the other means would have likely sufficed. But consider how many hours people will often spend tracking down a bug and not even know there is a methodology that could nail it in 30 minutes...when time is money (and being based out of NYC with the high costs, and "competition" from other areas with significantly lower costs - this is crucial).



  • A simple question (related to items discussed above)... You have a loop that allocates objects and puts them in a HUGE List<T> with Add(). Later in your code you need two things

    1) A sorted version of the list (which will be used first), based on some custom sorter.

    2) A copy of the list while will be repeatedly used many times in a for each (this will be used later)

     Should you make the copy from the original list (which means keeping the original around longer, or making the copy earlier), or from the sorted list (items are much closer to their first usage), or does it not matter at all?

    [This is a paraphrase of one of my general C# developer questions used during interviews] 



  • @Sutherlands said:

    @bjolling said:

    It's like you are proud you can do addition without using "plus" after discovering that 5 minus (-1) equals 6 and then calling me dense for telling you that in the background it is still an addition

    No, it's like I am proud that I can write good code and then calling you dense for telling me that it generates the same IL as bad code.

    Yes and no. 'using' corresponds to [code]try { ... } finally { dispose } [/code] so it means that there is an expensive try block that just lets exceptions fall through.

    But if you do want to catch the exceptions thrown from inside a 'using', you need to write (see also this code sample)

    try { 
      using ( recordset ) { ... } 
    } catch ( Exception ex ) { 
      Log.Exception(ex); 
    } 

    But because 'using' only is syntactic sugar, this in reality is exactly the same as writing: 

    try {
      new recordset
      try { ... } 
      finally { dispose recordset }  
    } catch ( Exception ex ) { 
      Log.Exception(ex); 
    }

    So your nice little trick is using two expensive try blocks for absolutely no benefit. The optimal way is as follows

    new recordset
    try { ... } 
    catch ( Exception ex ) { 
      Log.Exception(ex);
      throw ;
    }
    finally { dispose recordset } 

    The only point I wanted to make is that I expect my developers to understand this and care about this. You claim to write good code but still you post example code with a using block inside a try/catch. But it's always easier to call people 'dense' and 'fail', isn't it?



  • @bjolling said:

     so it means that there is an expensive try block that just lets exceptions fall through.

    The only point I wanted to make is that I expect my developers to understand this and care about this. You claim to write good code but still you post example code with a using block inside a try/catch. But it's always easier to call people 'dense' and 'fail', isn't it?

    You claim it is expensive...yet do not QUANTIFY the cost.  There is no argument that it will add clock cycles, but I think we all agree that this will only be an issue in a very rare set of circumstances, and that readability is key. A using block (while merely sugar) is detcted by many style analysis tools where the equivilant try/finally (with or with out the desired catch will not). Therefore by "optimizing" the code, you may make the code harder to maintain.

     ps: I am a performance junkie (partly by requirements, partly by personallity) and have spent many hours doing analysis of .NET...I know the answer to the question above....Just remember the JIT does most of the optimizations, so looking at IL in this case does NOT give the answer...



  • @TheCPUWizard said:

    @bjolling said:

     so it means that there is an expensive try block that just lets exceptions fall through.

    The only point I wanted to make is that I expect my developers to understand this and care about this. You claim to write good code but still you post example code with a using block inside a try/catch. But it's always easier to call people 'dense' and 'fail', isn't it?

    You claim it is expensive...yet do not QUANTIFY the cost.  There is no argument that it will add clock cycles, but I think we all agree that this will only be an issue in a very rare set of circumstances, and that readability is key. A using block (while merely sugar) is detcted by many style analysis tools where the equivilant try/finally (with or with out the desired catch will not). Therefore by "optimizing" the code, you may make the code harder to maintain.

     ps: I am a performance junkie (partly by requirements, partly by personallity) and have spent many hours doing analysis of .NET...I know the answer to the question above....Just remember the JIT does most of the optimizations, so looking at IL in this case does NOT give the answer...

    Well, it is 2am around here and the Visual Studio on the laptop that I'm currently using runs inside a VM. I'll never be able to get a decent qualification like that. I've always been told there is a performance hit by using a try/catch. But this StackOverflow question seems to agree with you that the cost is small.

    But I don't agree that try/catch/finally{dispose} is harder to understand/maintain than try{ using }catch.

    BTW: is that "our" DaveK that replied to it?

     



  • I'll simply echo what TheCPUWizard says and provide this link for you to read.  I don't particularly care what you find easier to read, because I don't work with you.  My team uses 'using' to take care of disposable objects because it's clear and maintainable.  Also - "But it's always easier to call people 'dense' and 'fail', isn't it?" - I'm not sure if you were deliberately trying to push my buttons when you came into this thread, but saying "Not sure what you are trying to prove" irks me, especially when followed up by something about how what I wrote is "the same" as something else... when it's not...



  • @TheCPUWizard said:

    I DEFINATELY expect someone to be able to draw a diagram of what happens in memory during each of the GC phases for each generation and for each GV type - unless they are applying for a position with "under one year of .NET experience".

    If you ever have to think for even a millisecond about this, you've failed. If you only hire developers who know this kind of pointless minutiae that hopeless geeks like you masturbate over, then you're probably excluding brilliant developers in the process.

    The correct answer to, "draw a diagram of what happens in memory during each of the garbage collection phases" is "who gives a fuck? Let's write some software!" Garbage collection is a solved problem. It might have been interesting a couple decades ago, it's an implementation detail now.

    Who gives a fuck, go write some software.

    While I'm fucking ranting:

    @TheCPUWizard said:

    but that is not the environment I have typically worked in for many years (decades)..

    Look, CPUWizard, we all know you love to brag about how many decades you've been in the industry, about being a New Yorker, about seeing some prototype Intel CPU, that you owned business, and all that other stupid pointless bullshit that you seem to imagine impresses people but in fact only makes them think you do nothing but stroke your own ego all fucking day long...

    But saying that you've been in the industry for decades is not necessarily a good thing. People who have been in the industry for decades are the reason I had to find a fucking C# library to read .ini files today. Today, meaning, "in the year 2012, fully 17 years after .ini files were made obsolete." Fuck those dinosaurs.



  • In response to Blakerant (I refuse to quote people who can not post rational or feel they must use foul language):

    IF GC is a "solved problem", then how come:  over $300K of my company's revenue in 2011 came from clients who had developed software that did not perform, and the root cause was invariably a lack of understanding of GC [This number has been a rough constant as a 20% percentage of business over the past 6 years]????

    You say "Let's write some software!"... I say "Let's write some quality software".  One of my pet peeves are people who still write applications that will not scale to make use of the multiple cores [woohoo, Kiefer has shipped with 32 cores, in limited quantities - March 2012].

    As to "stroking my own ego"...I dont see it that way at all. If someone is going to read something, then knowing something about the author puts it in context. My comments about being a New Yorker (if you actually read them) are about the difficulties the location brings, and not something to brag about at at...

    FWIW: There are multiple C# libraries readily available for ini files, so finding one should not have taken more than a few minutes. The native primitives are still part of the supported Windows API (not deprecated even in Windows 8), although I agree they should not typically be part of a modern (last 15 years) application.



  • @TheCPUWizard said:

    In response to Blakerant (I refuse to quote people who can not post rational or feel they must use foul language):

    Wow see what you did there. My name is "Blakeyrat" and you added an N to make it "Blakeyrant". Like, you're combining my name with the fact that it was a rant. And you even bolded the N so that we could all see how clever you were. That's just awesome.

    @TheCPUWizard said:

    IF GC is a "solved problem", then how come:  over $300K of my company's revenue in 2011 came from clients who had developed software that did not perform, and the root cause was invariably a lack of understanding of GC [This number has been a rough constant as a 20% percentage of business over the past 6 years]????

    Because your clients are idiots????????????????

    @TheCPUWizard said:

    As to "stroking my own ego"...I dont see it that way at all.

    Yes, well, that's great when you're talking to yourself, but there are other people here reading your crap.

    @TheCPUWizard said:

    If someone is going to read something, then knowing something about the author puts it in context. My comments about being a New Yorker (if you actually read them) are about the difficulties the location brings, and not something to brag about at at...

    I hate to break this to you, but everybody hates New Yorkers. Including other New Yorkers. You guys are the fucking worst. The financial collapse, 2008? All your fucking fault. Die in a fire.

    @TheCPUWizard said:

    FWIW: There are multiple C# libraries readily available for ini files, so finding one should not have taken more than a few minutes.

    Yes, because remember when I was ranting about how many hours it took me to insta-- oh wait I didn't spend more than a few minutes on it. And I just love adding random open source shit-libraries as dependencies because some other developer (probably a New Yorker with decades of experience) is a fucking asshat. My software is worse because he is an idiot. Fuck that noise.

    @TheCPUWizard said:

    The native primitives are still part of the supported Windows API (not deprecated even in Windows 8), although I agree they should not typically be part of a modern (last 15 years) application.

    Wow. You're exactly the type of dinosaur I'm referring to. I love the weasel word, "typically", because now you can say, "well I typically say not to use them but in this case...". No. No weasel words. Fuck that noise.

    .ini files are fucking obsolete. They're trash. If you use them, you're trash. You need to leave the industry and get a job picking up trash. Or recycling. I boldfaced this paragraph because I think that "trash talk" is pretty damn clever, as is the pun in this sentence.



  • Blakey...I can only wish that every post you make online shows up at every interview you go to for the rest of your life...it would save lots of people tons of grief...



  • @TheCPUWizard said:

    Blakey...I can only wish that every post you make online shows up at every interview you go to for the rest of your life...it would save lots of people tons of grief...

    I wish I had a unicorn.



  • @blakeyrat said:

    I wish I had a unicorn.

    You did, but some jackass declared it in a using block and now it's gone.



  • @Sutherlands said:

    I'll simply echo what TheCPUWizard says and provide this link for you to read.  I don't particularly care what you find easier to read, because I don't work with you.  My team uses 'using' to take care of disposable objects because it's clear and maintainable.  Also - "But it's always easier to call people 'dense' and 'fail', isn't it?" - I'm not sure if you were deliberately trying to push my buttons when you came into this thread, but saying "Not sure what you are trying to prove" irks me, especially when followed up by something about how what I wrote is "the same" as something else... when it's not...

    At first I just wanted to point out that by putting 'using' inside a try/catch, you'd effectively have two try blocks in IL. Since you put this in a reply to show how to dispose without putting the 'new' inside a 'try', I felt it necessary to point that in your code your 'new' was still inside a 'try'. Your example code did not prove your point. That's why I said I was not sure what you where trying to prove.

    I have nothing against 'using' and I use it all the time, except putting inside a try blocks feels counter-intuitive to me. Don't echo TheCPUWizard -- if that was your point all along, you could have said it before he joined the discussion. But you didn't so it wasn't

    That said, I followed TheCPUWizards advice and tried to quantify the cost of a try block. This is the first run of my test application

    Warming up
    Iterations: 500000
    NewRecordset                  : 241,957 ms
    NewRecordsetUsing             : 240,467 ms
    NewRecordsetTryUsing          : 239,920 ms
    NewRecordsetTryTryFinallyCatch: 242,363 ms
    NewRecordsetTryCatchFinally   : 241,064 ms
    

    This is the second run of my test apllication

    Warming up
    Iterations: 500000
    NewRecordset                  : 250,339 ms
    NewRecordsetUsing             : 249,909 ms
    NewRecordsetTryUsing          : 244,398 ms
    NewRecordsetTryTryFinallyCatch: 243,899 ms
    NewRecordsetTryCatchFinally   : 242,196 ms
    

    I think the names are descriptive enough. But anyway:

    • NewRecordset -- Just doing a new DataSet, call the clear function, test for null and dispose
    • NewRecordsetUsing -- Call the clear function inside a using(new DataSet) block.
    • NewRecordsetTryUsing -- like previous but wrapped inside a try/catch. The code that you proposed at first
    • NewRecordsetTryTryFinallyCatch -- unrolled the try/using/catch into try/try/finally{dispose}/catch
    • NewRecordsetTryCatchFinally -- removed the redundant try from previous line, ending up with try/catch/finally{dispose}

    I've executed it several times in a row and there seems no clear winner. Funnily enough, having an try block is not slower than having no try block at all. I guess that the rule is "exceptions are expensive when using to control the flow of an application when compared to doing it with an if statement". Someone else can test that.



  • @bjolling said:

    <snip>

    That said, I followed TheCPUWizards advice and tried to quantify the cost of a try block. This is the first run of my test application

    <snip>
    I've executed it several times in a row and there seems no clear winner. Funnily enough, having an try block is not slower than having no try block at all. I guess that the rule is "exceptions are expensive when using to control the flow of an application when compared to doing it with an if statement". Someone else can test that.

    First, thanks for taking the time to run and publish your results. What you have clearly shown is that the "cost" of try/catch is sufficiently small that it can not be measured because of the variances (some caused by .NET, some by Windows) in time are larger. While it takes a good amount of work to prove, I can add the following:

    * Consecutive "try { try { " is much less expensive than "try { somecode; try {" because there is no difference in the state at the start of the try blocks.

    * "finally" without any catch blocks is an optimized case, further reducing the cost. So if you inner block had also contained "catch" statements, the cost would be higher (using does not contain any catch blocks - so you case is good for analysis of the original point).

    * "successful" (non-throwing) code paths are MUCH cheaper than throwing code paths. So worst case timing would have the inner code atually throwing an exception.

    * The compiler (in this case the JIT) is allowed to re-order operations (in optimized builds without a debugger attached), provided that they do not produce visible effects. This is key in many cases.

    These are all things which have an impact on a program [the topic of which programs this impact is significant for is a different one..and also IMHO quite interesting]. Yet they are all things which can not be determined at the language level, requiring at least IL knowledge, and in many cases knowldge of the native code generated by the JIT.



  • @TheCPUWizard said:

    These are all things which have an impact on a program [the topic of which programs this impact is significant for is a different one..and also IMHO quite interesting]. Yet they are all things which can not be determined at the language level, requiring at least IL knowledge, and in many cases knowldge of the native code generated by the JIT.

    They are also all things you shouldn't give a shit about.



  • @blakeyrat said:

    @TheCPUWizard said:
    These are all things which have an impact on a program [the topic of which programs this impact is significant for is a different one..and also IMHO quite interesting]. Yet they are all things which can not be determined at the language level, requiring at least IL knowledge, and in many cases knowldge of the native code generated by the JIT.

    They are also all things you shouldn't give a **** about.

    I am sure bosses/employers/clients would love to hear that ("I don't give a **** that the code I wrote for you is useless") when their program is failing to meet performance requirements [see: which programs this impact is significant for in my post above].  Many HFT programs directly translate microseconds of execution speed to potentially thousands of dollars (per execution). Many industrial control applciations, translate these same timeframes to safety (equipment damage, personal injury) related effects.

    Even many "conventional business programs" suffer when scaled to significant size (tens of thousands of transactions per second). In these cases, "scale-out" may be an option, but that introduces additional concerns about synchronization which may make things worse (or at least much more expensive)


Log in to reply

Looks like your connection to What the Daily WTF? was lost, please wait while we try to reconnect.