5 ms·
I'm not one to hate on C#, or be a programming language snob but this certainly looks like a case where poor performance and a lot of extra work were created si
by steve8918 15y ago
I'm not one to hate on C#, or be a programming language snob but this certainly looks like a case where poor performance and a lot of extra work were created simply because of a deficiency in a language. Languages like C# are advertised as being simple to use, and for the most part they are. They fit the bill in a lot of different use cases.
But it certainly seems like to me that if you want to build a high-performance, scalable piece of software, you don't want to have to bang your head against wall and fight against deficiencies within the language implementation itself in order to get your software working properly.
- mwsherman 15y agoYou are conflating the language with the runtime, first. And second, we were experiencing the occasional page taking maybe one second, which we considered unacceptable but 99% of the world wouldn’t notice. (NB, languages like Ruby and PHP are lovely, but are over 10x slower than C# and Java.)
- steve8918 15y agoYes, sorry, I meant implementation of the language, ie. CLR. That being said, having to rewrite an entire engine because of the underbellies of the CLR seems to be dubious, especially in the case of a development environment that purports to make life easier for the developer. I have nothing against C#, one of the trading frameworks I use uses it exclusively (Ninjatrader) and it's pretty nice. It's just that I would hate to have invested weeks/months into a software project, using what I imagine would be tried-and-true software techniques, and then have to rework them to get over the particulars of the implementation. That being said, I guess all languages have similar problems. For example, when I was working on a backend server back in 2001, we found that our product was "leaking" memory on HP-UX, even though none of memory leak detectors found any problems, and the memory leak problem didn't occur in Solaris, AIX and Windows (we had a cross-platform server). It turns out on high-load systems, our app was allocating a bunch of small strings all over the place, and the base memory allocator for HP-UX was causing memory fragmentation over time. By switching to another memory allocator that handled this situation, it fixed the problem. I guess there aren't any C/C++ books that I've come across that say "don't allocate a millions of small memory blocks because your memory might fragment, even though you free them properly." So maybe I misspoke, I guess to some degree it does manifest itself in all implementations of languages.
- underwater 15y agoIsn't that the issue Firefox was having with their so-called "memory leaks"?
- Roboprog 15y agoI'm so tired of benchmarks that play with ints and floats which show how fast Java is. Most business app work is string manipulation. If you think Ruby is slow, look at the timings for "sequential" operation in the table on this page (yes, it's my site): http://roboprogs.com/devel/2009.12.html http://roboprogs.com/devel/2009.12.html If you think that I have badly blundered in my methodology, get the benchmark code, fiddle with it, and run it on your own hardware: https://github.com/roboprog/mp_bench https://github.com/roboprog/mp_bench FYI: I'm not trying to say that "Ruby is the most awesomest language, like ever, d00dz!!!". I like different tools for different jobs. I'm just tired of seeing people judge implementation speeds based on bit twiddling benchmarks, rather than stuff that at least churns through a large number of strings, if not other object types, and does some I/O.
- jbooth 15y agoYou're comparing the library-supplied date formatter for each language, not the language's speed at processing Strings. And the Java threading code is mostly benchmarking the speed of thread creation - in a real-world implementation you'd be using a thread pool with fewer lines of code.
- Roboprog 15y agoAgreed about the thread usage: the code I put together for threads in various languages is as naive as possible. Having a thread pool in proportion to the number of CPUs and pulling tasks from a queue (a la "Nginex") would be much more efficient. Interesting comment about the date formatter. I might put in something some time to compare the relative time spent in formatting vs the other concatenation. I suppose I'd be grateful if somebody made a fork with versions showing the split of time between those steps.
- qw 15y agoI noticed some differences in the code that I think are not equivalent Perl: print $local_process_var, " ", &gen_pg_template(), "\n" Python: print local_process_var, " ", gen_pg_template() Java: System.out.println( timestamp + " " + genPgTemplate() ); I'm not sure, but I think the Perl/Python code sends the strings as arguments to print that will just output them directly. In Java you will concatenate 3 strings before sending it to "print". This adds some extra CPU usage that the other versions don't have
- jpeterson 15y agoHow is this a defficiency in the C# language, exactly? Sounds more like an issue in the current version of the .Net CLR to me.
- brown9-2 15y agoWhat is the deficiency? How do other languages solve problems created by unfortunate coincidences between your usage pattern and the GC's timing?
- mrgoldenbrown 15y agoSome languages solve this problem by not having a GC at all :) However, with a problem involving huge in memory structures like this, even manually allocating and deallocating everything properly would probably be a non trivial thing.
- dos1 15y agoPray tell, what language or framework would not experience minor performance issues running at the scale they do?
- kristiandupont 15y agoSo would you go with c or c++? Because otherwise I would say that the consensus is that c# is in the higher end of the performance scale.
- Roboprog 15y agoI can't say that the Java Virtual Machine would have done much better, since it operates under pretty much the same theory (generational garbage collection). At least Ruby has the option to mark some strings as outside of garbage collection -- to make them permanent symbols/atoms. We need an option in these modern GC languages to select a reference counting option, or perhaps for portions of code to kick it old school and simply ask for some objects to allocated outside the GC heap on the assumption that they will be around for a while and that the programmer will manually throw that subset of objects away if they become unwanted. TMTOWTDI. (and all ways seem to have their place at times)
- kmontrose 15y agoYou can intern strings manually in .NET (I think you can in Java too), which effectively makes them ineligible for collection. There are serious memory concerns with that approach, since nothing in the tag engine is a constant. In C# you can use the unsafe keyword to get more or less back into the C/C++ world. While your new'd objects are still GC'd, you have the option of just grabbing an allocator and getting unmanaged memory if you feel like it. It's worth noting that the .NET GC works quite well for typical cases, and only noticeably chokes on this one use case we have and only under load that most websites will never see (and most users don't notice even on SO, but we watch the logs religiously to make sure these things don't become noticeable). There are also some improvements coming in .NET 4.5's GC that may mitigate this, but we're naturally not willing to wait for it. I worry people may be taking "don't use .NET, its GC sucks" away from this blog post, which really isn't the point (or accurate).
- dbattaglia 15y agoI worry people may be taking "don't use .NET, its GC sucks" away from this blog post, which really isn't the point (or accurate). I get the feeling some already came in with that opinion, so they will take away what they want to. I personally got the impression that this is something that would have caused pain in almost any language with a generational GC.
- Roboprog 15y ago