Linked by Rüdiger Klaehn on Wed 6th Oct 2004 20:31 UTC
.NET (dotGNU too) The current implementation of generics in .NET 2.0 does a very good job to make typed collections faster and more easy to use. But as many people have noticed, it leaves much to be desired when you want to do calculations with generic types.
Order by: Score:
Needs a Careful Read...
by The Matt on Wed 6th Oct 2004 21:24 UTC

I'm primarily a scientific programmer working with Fortran 95, so this article peaked my interest. But, I think I'm gonna need a good intro to .NET before tackling this. Any Fortran 95+.NET'ers out there who can help me translate what he wants to do into Fortran-speak?

v @Rudiger Klaehn
by Lumbergh on Wed 6th Oct 2004 21:57 UTC
Worth it ?
by GS on Wed 6th Oct 2004 22:24 UTC

I'm a scientific programmer too, but can anything beat the elegance of C/F90 ?

Stick with C++ and your problems are gone
by Anonymous on Wed 6th Oct 2004 22:52 UTC

Just stick with C++ and forget about problems like this. If you absolutely have to use this .NET framework I'd suggest going with C++/CLI which still allows you to use its almighty templates.

v @Lumbergh
by Rayiner Hashem on Wed 6th Oct 2004 23:03 UTC
Efficiency
by Beldraen on Thu 7th Oct 2004 00:25 UTC

I always get a kick out of issues, like generics. I'm sure there are a few places where really tight loops are necessary, but just how many places who implement generics really need it? Most computers burn away their time just sitting there doing nothing 99% of their lives. So, let's say that you really have a process that takes a few hours each time to run and getting that 30% boost can make a difference. Does the extra five minutes it takes to write a specific data-typed version justify the time it took to figure out how to write a generics version that could be used for just a few elemental data types? There is always a trade between specific code (more understanble, but less maintainable) and generic code (more flexible, but slower and more difficult to understand). Generics just seem like a good way to get both less maintainable and more difficult to understand, both of which many "lowly" programmers have difficulties.

My two cents,
Bel

P.S. Good article, though. Personally, if I really felt the need, we're going to be going to be more complex anways, so emit the byte code and get all your "money's worth" from the complexity and hide it in a black box for end users.

@Bel
by Shadowlight Dancer on Thu 7th Oct 2004 00:38 UTC

Gaming, dude. C# can be used for serious gaming projects - and it is. In the Axiom Engine, its about a 40FPS boost just by implementing generics... probably 20 or 30 FPS more by tweaking the implementation.

XAML
by Anonymous on Thu 7th Oct 2004 00:39 UTC

I little bit off topic ... but when (meaning rough date) can I expect to see XAML support? Also, will XAML support be in .NET version 2?

Thanks

hmmm...
by Zambizzi on Thu 7th Oct 2004 00:56 UTC

.NET 2.0? Why? I can do this now in Java 5.0 (1.5)...

RE: Zambizzi
by Barlin on Thu 7th Oct 2004 01:05 UTC

Yeah you can, but don't you get no performance gain from Generics in Java?

fortran will survive without .net
by tech_user on Thu 7th Oct 2004 01:08 UTC

there is no need for the additional gumpf that comes with .net and even such data abstractions and colelctions.
this strong statement is supported by the fact that both C and Fortran are still used and thriving in the numerical computation fields.

the poster who suggests that computers do nothing 99% of the time is missing the point. computers are worked hard for those short periods when you need anwers. that is the region of interest. and if you can compyte 5% faster then yu may churn through 150,000 more anti-cancer drug combinations in a month. that's not to be laughed at.

myself i am glad that the scientific community have always been unfazed by geeky and glamourous trends in computing. to them/us, a computer is a number cruncher with storage and languages are not religous but differen t balances in the space of domain specificity and abstraction. nothing more.

Re: Stick with C++ and your problems are gone
by javaithan on Thu 7th Oct 2004 05:13 UTC

Java has REPEATEDLY been shown to be faster than native code in several numerical transforms. This is due to the JVM's ability to dynamically optimize the code, where as C++ gets one shot to optimize and has no idea what's actually been going on at runtime.

That said this just shows the whole fallacy of C#'s approach to generics. Java has done a much better job with them in Tiger if you ask me. While it's nice generics work with reflection in .NET, the performance toll is too large to be ignored.

Confused
by Brian Matzon on Thu 7th Oct 2004 05:34 UTC

Hmm, I was under the impression that Java Generics sucked, and .NET's implementation ruled the world - can someone enlighten me? Preferably articles, not fanboyish statments.

C++ templates are an ugly hack, period. And C# and other .NET languages have much more advanced features than C++, at least in the 2.0 version. Take a look at the strange things you have to do to get real closures in C++ (Boost::Lambda). In C# 2.0 they come with the language as anonymous delegates.

.NET generics is the nicest generics system I know of. C++ templates are a pure compile time feature that produces horrible code bloat. And java "generics" are a joke. They are just for better type-safety and cleaner syntax, but do nothing at all about the problem of excessive boxing/unboxing even for trivial cases.

Re: javaithan
by Rüdiger Klaehn on Thu 7th Oct 2004 05:38 UTC

"That said this just shows the whole fallacy of C#'s approach to generics. Java has done a much better job with them in Tiger if you ask me. While it's nice generics work with reflection in .NET, the performance toll is too large to be ignored."

You do not know what you are talking about. In java, generics is just a feature to eliminate casting and to enhance type safety. Deep down it is all objects. So if you have a List<int> in java, it is internally represented by an object[], so you will have boxing/unboxing everytime you access or modify the list. In .NET a List<int> uses an int[] internally, so no boxing or unboxing whatsoever.

The performance of .NET generic code will be 5 to 10 times higher than the performance of java generic code. If you don't believe me, I can post a benchmark that you can try on your own machine.

Re: javaithan (IP: ---.com)
by Bascule on Thu 7th Oct 2004 06:30 UTC

Java has REPEATEDLY been shown to be faster than native code in several numerical transforms. This is due to the JVM's ability to dynamically optimize the code, where as C++ gets one shot to optimize and has no idea what's actually been going on at runtime.

Wrong?

http://fails.org/benchmark.html

The JVM's main runtime optimization feature to be touted is the inlining of virtual methods. If virtual methods are being abused in performance critical C++ code I'd say it's more an indication of poor programming than a substantial language drawback.

I work in scientific computing and we would never consider using Java. Our model is written in Fortran 90 which is, and will likely remain, the primary language utilized in scientific computing.

@Rüdiger Klaehn
by Anonymous on Thu 7th Oct 2004 07:34 UTC

"C++ templates are an ugly hack, period."

We agree on disagreement. I think of C++ templates as a very powerful tool, not as a hack. I would also tend to think that implicit constraints are an advantage. If you have to use constraints you can have them. Say you want something like ICompareable. You use like this (Can't use usual template syntax here ate OSNews. Substitute the » and « with > and <):

template « typename T »
class Subject : private Comparable «T»
{};

and implement Comparable as follows:

template « typename T »
struct Comparable {
static void constraint(T a, T b) {
(void)(a < b);
(void)(a == b);
(void)(a > b);
}
Comparable() {
void (*p)(T,T) = constraint;
}
};

Look at http://www.artima.com/cppsource/wishlist.html if you want to read more. But anyway I prefer implicit constraints anyway.

"C++ templates are a pure compile time feature that produces horrible code bloat."

You have a common misconception here. First I think it must be quite embarrasing for you to dismiss C++ for "code bloat" when you use .NET which is quite a memory hog. In comparisson C++ is *very* effcient. Concerning your code bloat argument. Earyl compilers surely produced multiple instantiations for different argument parameterization. Modern compilers tend optimize quite a few cases away.

RE: Efficiency
by Sander Stoks on Thu 7th Oct 2004 08:02 UTC

Most computers burn away their time just sitting there doing nothing 99% of their lives. So, let's say that you really have a process that takes a few hours each time to run and getting that 30% boost can make a difference. Does the extra five minutes it takes to write a specific data-typed version justify the time it took to figure out how to write a generics version that could be used for just a few elemental data types?

Yes, if the 30% boost means you can process every frame in a continuous data stream, instead of every other frame. Also, maybe your computer is idle 99% of its life; in scientific computing it is no exception having to buy CPU power by the minute. Those super computers are so hideously expensive that they make sure they are working all the time.

Generics just seem like a good way to get both less maintainable and more difficult to understand...

That depends on how generics are implemented. I would agree with you having read the lengths you need to go to to get decent performance out of .NET generics, but if you consider C++ templates, how is

template<typename T>
T add(const T& a, const T&b)
{
   return a + b;
}

hard to read..?

RE: Efficiency
by Sander Stoks on Thu 7th Oct 2004 08:04 UTC

Aaaargh!!! I hate the HTML parsing on this forum. The preview button shows  , < and > correctly but doesn't understand the UBB tags, and when the post shows up it's the other way around. Sigh.

Re: Anonymous
by tuttle on Thu 7th Oct 2004 12:16 UTC

"We agree on disagreement. I think of C++ templates as a very powerful tool, not as a hack."

Of course C++ templates are powerful. But so is the C preprocessor. A feature can be both very powerful and very hackish.

"I would also tend to think that implicit constraints are an advantage. If you have to use constraints you can have them."

I am not sure wether implicit oonstraints are better or worse than explicit constraints. On the one hand, implicit constraints are easier to use for the class library author.

But on the other hand, they make it very easy to add too many constraints, they go against the grain of a strongly typed language, and they produce very unhelpful error messages when something goes wrong.

But my main problem with C++ templates and C++ in general is that everything is done during compile time. There is almost no runtime type information available, so you have to graft strange extensions like the Qt moc on top of it all for many applications. Rtti is very limited.

In .NET, you have a large amount of runtime type information, and you can easily produce dynamic methods and such. For example the regular expression engine of .NET works by emitting MSIL code for each pattern, which then gets compiled to native code by the JIT. The result is very high performance regular expressions. Try something like this in C++.

Another thing to keep in mind is that a highly optimizing JIT will produce faster code than a static compiler, and automatic memory management with gc is often faster than manual memory management. So in the long run managed languages using an intermediate representation and a JIT will be both faster and easier to use than nonmanaged languages.

There are many bechmarks where java and .NET outperform C++ even now.

RE: Anonymous
by Sander Stoks on Thu 7th Oct 2004 14:10 UTC

But my main problem with C++ templates and C++ in general is that everything is done during compile time.

That is an advantage. Make the compiler work for you, instead of only finding out at run time and having to throw an exception in the user's face.

Re: Sander Stoks
by tuttle on Thu 7th Oct 2004 14:49 UTC

"That is an advantage. Make the compiler work for you, instead of only finding out at run time and having to throw an exception in the user's face."

You should take a look at the .NET generics approach before dismissing it. Type safety is enforced at compile time using type parameter constraints, so you won't "throw any exceptions in the user's face".

But the specialization and instantiation of the generic types is done at runtime, which makes the whole approach much more flexible. And a good JIT will make them perform just as well as the C++ equivalent.

Limitations
by Anonymous on Thu 7th Oct 2004 15:27 UTC

Generics do not allow user partial specialization, type parameter inheritance or non-type parameters (in fact *only* ref classes or val classes). They present a very limited form of generic programming (something they have in common with Java's approach).

I don't get it..
by verbat on Thu 7th Oct 2004 18:13 UTC

if you want fast calculus, why don't you simply use a fast library?
I mean, even scripting languages have them (python's Numarray or ruby's NArray come to mind) no chance to have them in c# ?

Do MS really want us to do fast numerical calculi by ourself, without esternal libraries or this is just a kind of strange premature optimization for a not ever rising problem?

The artcile was nice to read anyway, thank you.

Re: Anonymous
by Rüdiger Klaehn on Thu 7th Oct 2004 19:16 UTC

.NET generics were not meant to be some kind of compile-time mini language which can be abused to calculate factorials and such. They exist solely to make it possible to write types and methods with generic type parameters for e.g. collections. And they do this fairly well and with no noticeable performance overhead (as opposed to the java version which has horrible performance).

Besides, C++ templates are very limited in their own way: for example you can not specialize a template for a type you do not know at compile time. And AFAIK C++ templates does not support type inference at all.

There are workarounds for emulating non-type parameters in .NET generics. And you can also do quite weird stuff with them using nested type parameters. Maybe I will write another article about this topic.

Re: Verbat
by Rüdiger Klaehn on Thu 7th Oct 2004 19:25 UTC

I have no idea what MS wants us to do. They probably don't know yet either, since .NET Whidbey (2.0) is not even out yet.

Of course you can use the established numerical libraries like LAPACK, BLAS etc. from .NET. I was just curious about the .NET generics implementation, its advantages and limitations.

As it turns out, generics in .NET are very fast and you can find usable workarounds for most limitations.

@Rüdiger Klaehn
by Anonymous on Thu 7th Oct 2004 23:04 UTC

C++ templates are actually even Turing complete, but I agree that it is of no practical use most of the time. In reference to your other point--the "abuse" of templates--templates allow for a very flexible kind of programming style based on policies and traits which is impossible to achive in C#. But then it is as you said--C# generics were ment to provide typesafe collections and simple algorithms (half the power, half the price).

Not sure what you could mean by type inference in this context. Often you can omit template parameters which are then deduced by the compiler, but in general you have to provide them. But where does C# use type inference?

Could you explain to me what you meant with: "you can not specialize a template for a type you do not know at compile time"? Thank you!

Re: Anonymous
by tuttle on Thu 7th Oct 2004 23:26 UTC

For example if you dynamically load a type T from an assembly (shared library/dll) at runtime and want to dynamically create a List<T> to store instances this type. This is not possible in C++. But of course dynamically loading a type from a dll is impossible anyway, so that might not be a problem for the stuff C++ is usually used for.

Another thing about C++ templates is that you have to have the source code to use a template. I guess there are various proprietary precompiled header formats, but you can not have a shared library or dll containing a template library. There is no stl.dll. Instead stl implementations are distributed as hundreds of .h files containing the source code.

The result is less flexibility, no code sharing between applications and much longer compile times. If there was something like the stl for .NET you could swap the stl implementation of your program without recompiling by just replacing the stl.dll in your programs directory with a newer version.

@tuttle
by Anonymous on Fri 8th Oct 2004 07:29 UTC

Thank you for your reply. Just wanted to let you know that there will be a STL.NET for C++/CLI in Visual C++ 2005 which should overcome the source code only limitation.

C++ is quite a static language which does not allow for everything that is possible in relatively more dynamic languages such as Java or C#. I can live with this static nature--in fact I've never been a fried of dynamic languages anyway, but that's another issue.

Re: Anonymous
by tuttle on Fri 8th Oct 2004 09:14 UTC

You should try a dynamic language. Stuff like this http://www.lambda-computing.com/products/utils/parser would never be possible with a static language.

Being able to run tests on a library binary without recompiling it (like NUnit does) is also very nice.

Re: tuttle
by Anonymous on Fri 8th Oct 2004 09:36 UTC

It is not that I don't know dynamic languages (I know Python) but my main background is Ada95 and C++ in industrial settings with tight time constraints (*cough* realtime *cough*). I always found the runtime behavior of static languages much more predictable but if I would have to write complex parsers or theorem provers I would not hesitate to use a functional language (eg. Haskell). But that's not were my focus is currently.

Re: Anonymous
by Rüdiger Klaehn on Fri 8th Oct 2004 10:59 UTC

I am not going to suggest dynamic languages for hard realtime applications for you. That would be dangerous at the current state of technology.

But the problem of the garbage collector permanently causing long (several millisecond) breaks can be solved in .NET by using structs, which do not use the garbage collector at all.

A .NET program that is careful to allocate all objects it needs at startup and that avoids temporary object creation by using structs will have very predictable runtime behavior. Since .NET uses a one-time JIT, there is no dynamic recompilation happening like there would be with Java HotSpot.

I found .NET good enough for "soft" real-time stuff like games or audio/animation stuff where you do not want any jerks due to garbage collection, but nobody gets killed if there is an unexpected 50ms break once every few hours.

YMMV, of course.