8 ms·
Try-catch speeding up my code?
- driax 12y agoNotice that this question is 2 years old. I would imagine that several lots of things have happened for Roslyn. (They even talk about some of what they were working on). Nevertheless quite interesting.
- nutjob2 12y agoIt's a compiler bug.
- teebot 12y agoI wish I could say that more often
- hugi 12y agoNo you don't :)
- dllthomas 12y agoMore often per unit of bug, maybe (... maybe.). No more often per unit of time or unit of code, please!
- LeonM 12y agoBelieve me, you really don't!
- teebot 12y agoyou're right it must be really tricky to spot and work around it but just the tought of blaming the compiler not sloppy programming is amusing
- mikeash 12y agoHaving found way too many bugs in the OS and compiler, it's amusing at first, but then gets tiresome. It's way easier to fix a bug when you're the one at fault, so any time something looks like it might be in the compiler or OS, I end up fervently hoping that it's not.
- yaur 12y agomaybe try compiling stuff with GCC 2.96 until you get that out of your system. I'm personally very happy that its been years since some weird behavior turned out to be a compiler bug.
- qntmfred 12y agothere is something oddly satisfying about stumbling upon compiler bugs. here's one i discovered a while back http://stackoverflow.com/questions/11303732/x86-vs-anycpu-returning-different-results-on-max-when-used-with-ternary-opera http://stackoverflow.com/questions/11303732/x86-vs-anycpu-re...
- fulafel 12y agoPuzzling that so many people still run in i386 mode. I haven't used a 32-bit system since shortly after x86 hardware went 64-bit, 10+ years ago. I guess in the Windows world it's because of XP?
- listic 12y agoI run in i386 becaues it uses less memory (though I think I'll be switching)
- davidw 12y agoYeah, on hosting systems where memory costs money, 32 bit can be a significant savings. I wrote this a few years ago: http://journal.dedasys.com/2008/11/24/slicehost-vs-linode/ http://journal.dedasys.com/2008/11/24/slicehost-vs-linode/
- listic 12y agoAlso, there are often cases where memory on your computer is either non-expandable or already maxed out. I maxed out my laptop with 8 GB and I don't feel like I have memory to waste with the usual office tasks, on Ubuntu. Being conservative and remembering that Ubuntu switched to "recommending" its 64-bit variant as default on its start page less than a year ago, naturally I chose 32-bit the last time I reinstalled the system. But, I'll choose 64-bit next time, because I see mainstream software support shifting to 64-bit for some applications, and because I read up Phoronix tests where 64-bit shows noticeable performance advantage.
- dbaupp 12y agoLinux offers the x32 ABI[1] for this reason: small 32-bit pointers but maintaining the advantages of x86-64 (more/bigger registers etc). [1]: http://en.wikipedia.org/wiki/X32_ABI http://en.wikipedia.org/wiki/X32_ABI
- deleted 12y ago[deleted]
- userbinator 12y agoI wasn't surprised to see it had to do with register allocation, since I've encountered some extremely odd compiler output with similar issues before. "Why would it ever decide this was a good idea?" is the thought that often comes to mind when looking through the generated code. Register allocation is one of those areas where I think compilers are pretty horrible compared to a good or even mid-level Asm programmer, and I've never understood why graph colouring is often the only way that is taught because it's clearly not the way that an Asm programmer does it, and is also completely unintuitive to me. It seems to assume that variables are allocated in a fixed fashion and a load-store architecture, which is overly restrictive for real architectures like x86. There's also no interaction between RA and instruction selection, despite them both influencing each other, whereas a human programmer will essentially combine those two steps together. The bulk of research appears to be stuck on "how do we improve graph colouring", when IMHO a completely new, more intuitive approach would make more sense. At least it would make odd behaviour like this one less of a problem, I think.
- xxs 12y agoI always thought the advent of RISC was a side effect of the (very) low register count and how hard it is to actually make optimal use of them without manually writing Assembler. The flat memory model on i386 at least made it somewhat easier compared to the segment address mode coming with 8086.
- jmgrosen 12y agoHaving just reverse engineered some 16-bit DOS code, I agree with your last statement wholeheartedly. That was scary.
- mzl 12y agoThe simple explanation why is that both problems are very hard to solve in isolation. Combining the problems makes it even harder. That said, of course it is better to try to solve the real problem and not only the decomposition. I think that the focus on cheap compiler passes is a bit obsolete now. A cheap debug-build with some optimizations is good, but for a real production build where speed is needed I am willing to wait quite some extra time to get the last few drops of performance. I've seen some researchers looking into solving the combined problem which feels promising. That kind of interest combined with the nice modularity of LLVM makes me quite optimistic that there will be nice results that are relevant both academically and industrially.
- stinos 12y agoOne of the nice things about this question (apart from the serious in-depth answers) is that Eric Lippert himself comes with an answer after discussing it directly with the people that can actually provide the proper fix. Q&A at it's best! edit same goes for Jon Skeet of course, and looking for info about him I came across this http://meta.stackexchange.com/questions/9134/jon-skeet-facts/9235 http://meta.stackexchange.com/questions/9134/jon-skeet-facts... which has some hilarious ones like Jon Skeet's SO reputation is only as modest as it is because of integer overflow (SQL Server does not have a datatype large enough) and When Jon Skeet points to null, null quakes in fear.
- gorhill 12y agoI actually have a similar question re. js since a while now [with Chromium 34]... Consider these two pieces of code which do exactly the same thing, one is a standalone function: var makeKeyCodepoint = function(word) { var len = word.length; if ( len > 255 ) { return undefined; } var i = len >> 2; return String.fromCharCode( (word.charCodeAt( 0) & 0x03) << 14 | (word.charCodeAt( i) & 0x03) << 12 | (word.charCodeAt( i+i) & 0x03) << 10 | (word.charCodeAt(i+i+i) & 0x03) << 8 | len ); }; The other a method: var MakeKeyCodepoint = function() {}; MakeKeyCodepoint.prototype.makeKey = function(word) { var len = word.length; if ( len > 255 ) { return undefined; } var i = len >> 2; return String.fromCharCode( (word.charCodeAt( 0) & 0x03) << 14 | (word.charCodeAt( i) & 0x03) << 12 | (word.charCodeAt( i+i) & 0x03) << 10 | (word.charCodeAt(i+i+i) & 0x03) << 8 | len ); }; var makeKeyCodepointObj = new MakeKeyCodepoint(); Now why the standalone function runs at over 6.3M op/sec, while the method runs at 710M op/sec (on my computer)? Try it: http://jsperf.com/makekey-concat-vs-join/3 http://jsperf.com/makekey-concat-vs-join/3
- SixSigma 12y agoThey are not exactly the same ergo they are different.
- gorhill 12y agoThe "two pieces of code" I am referring to are obviously the body of the function and method. (Following your comment I had to look again, I thought I missed something).
- amalcon 12y agoWhich JS VM are you using to test this? That matters a lot for this sort of thing. I ran it past the one in my browser (current Firefox, Linux) and didn't see a significant difference.
- gorhill 12y ago
- logn 12y agoI don't code in C# but it would be interesting to surround the code in just a block instead of a try-catch block and see if the same behavior is evident. If a plain block is still slow, then maybe branch prediction gets overwhelmed with considering having to unwind the stack all the way to main and dealing with open streams and objects on the stack. edit: I don't know byte code or machine code well so my description of what happens unwinding the stack is probably wrong, but my point is just that it's simpler for the CPU not having the possibility of unwinding the stack beyond the code section OP called out.
- batmansbelt 12y agoIt's literally the best feeling in the world when Eric Lippert answers your c# question. It's like if you cried out "dear God, why?" about your troubles but actually got a response.