Rusky
|
|
Reply #15 Posted on: April 06, 2010, 11:16:48 am |
|
|
Joined: Feb 2008
Posts: 954
|
C# and Java are compiled when they're run rather than ahead of time, which makes it much more cross-platform, because you just need to port the runtime once and you just need to distribute one version of the executable. It also gives you better optimization, because you know exactly what hardware you're running on. In languages where automatic parallelization is possible, for example, you can tune it to the number of cores you're running on.
Java and C# are at least as predictable as C and C++. They run as machine code, just like C/++, and while they have extra logic implicit in the code, C and C++ do as well. Yes, C/++ is much closer to the hardware, letting programmers do (and mess with) much more stuff themselves, but that doesn't make them any more predictable.
C/++ is still used for games because of portability (to game consoles without .NET or the JVM) and sometimes for speed- games are insanely real-time compared to other types of applications and they can't always handle GC's relative unpredictability. However, a lot of games are written in XNA, which runs on Windows, XBox, Zune and eventually Windows 7 phones. This is a library designed specifically for games- so yes, people are starting to write new engines in these higher level languages.
Java and C# can be used to write kernels; there are even a few kernels written in Haskell. These kernels only use non-Java/C# code to JIT the rest of the kernel and the programs running on it; the Haskell ones use non-Haskell for the same things as C kernels. Most of the kernel is written in Java/C#. The only reason you can't write kernels completely in higher-level languages is that they (including C/++) don't give you access to processor-specific instructions. On a simpler CPU, you could write a kernel with absolutely no assembly.
@retep: You have absolutely no idea what you're talking about. The scheduler is pretty much always written in C. The only parts you need assembly for are device I/O and CPU-specific functionality like paging and interrupt management, of which the CPU-specific parts are relatively small.
|
|
|
Logged
|
|
|
|
luiscubal
|
|
Reply #16 Posted on: April 06, 2010, 11:49:24 am |
|
|
Joined: Jun 2009
Posts: 452
|
Different computers have different hardware. Some processor-specific optimizations fail when you switch computers. Also, on prediction of C and Java, consider this code: //C++ if (x != NULL) x->someField = 2;
//Java if (x != null) x.someField = 2;
In Java, I can predict that someField of x will become 2. In C, I can predict nothing. In spite of the check, the application could still crash(segfault) if, for instance, x was free()d. When I write code in C, the spec states what happens. Ok, that's predict. But - guess what? - the same applies to Java. If nothing else, Java is MORE predictable than C because there is less *undefined behavior*(which C has plenty). So, I said it and I'll say it again - as a language, C is great for low-level tasks. For high-level tasks, it is basically the same as Brainfuck(where everything is technically possible, just like in C). You're complaining that Java/C# are too high-level when it's their greatest advantage. This is not 1970 anymore. Most tasks no longer require such low-level tools. You can theoretically dig a 100km-wide hole, but nobody does it. The right tools for the right job. Possibility is irrelevant. What matters is viability. EDIT: Just found this gem in Wikipedia: Ngen pre-compiles (or "pre-jits") bytecode in a Common Intermediate Language image into machine native code. As a result, no runtime compilation is needed. .NET framework 2.0 shipped with Visual Studio 2005 runs Ngen on all of the Microsoft library DLLs right after the installation. So it appears that even your beloved .NET DLLs are compiled. Worse - they combine the optimization advantages of JIT with the minimum startup delay of AOT!
|
|
« Last Edit: April 06, 2010, 12:18:30 pm by luiscubal »
|
Logged
|
|
|
|
Josh @ Dreamland
|
|
Reply #17 Posted on: April 06, 2010, 01:34:07 pm |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
I see people comparing the Java-C++ relationship to that of C++-assembly. The difference seems to be that in C++, I can say asm("") to get to a faster language. In Java, you're pretty much stuck with what you have. Getting ENIGMA, as a DLL, to work with LateralGM has been one of the most tedious processes I've ever undergone while programming. The only worse experience was in GML, where I'm never sure if it's an error or if I'm truly missing something (twice out of three it's proven to be the former; the third time was inconclusive). But that's neither here nor there.
I am reasonably certain that everyone in this topic is aware of the concept of JIT compilation. It offers a lot of neat tricks. The problem is, it requires a large runtime that isn't necessarily portable to all systems.
High, high level scripting languages (GML is NOT in this group; GML offers so amazingly little that it isn't funny), I'm talking mostly about Python and Haskell, maybe even Lua (though I'm not aware of the particulars of that language), are relatively easy to embed in a C++-compiled program. By relatively, I mean easily done with a good library. Granted, true interface is difficult, but small-scale embedding is just not that hard to pull off. My best example is JavaScript via V8, hence me considering using it for the interpreter. V8 seamlessly integrates the two languages; I can call JavaScript from C++; the JavaScript can call C++ methods and functions. And it's JIT compiled, which means it has amazing speed relative to regular, interpreted versions.
|
|
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
luiscubal
|
|
Reply #18 Posted on: April 06, 2010, 01:43:37 pm |
|
|
Joined: Jun 2009
Posts: 452
|
JNI/JNA and P/Invoke, Josh. Assembly is relatively minimalistic. C++ is a whole world. So adding Assembly to C++ is relatively easy. Adding C++ to Java/C# is not trivial.
But yes, this whole Java-vs-C++ debate is pretty much like old C-vs-Assembly debates. The C guys trying to convince the Asm guys that C isn't that bad, that C solves some problems easily when Assembly is highly complex and Assembly guys saying that Asm does everything that C does and more(interrupts, anyone?) and that C is "far too slow" and "forces specific methods instead of giving freedom"(such as register allocation), with the C programmers saying that C is no longer as slow as it used to be and is relatively capable of competing with Assembly, even if well-coded assembly is faster than C.
But yes, we are mostly in a transition period which is kind of painful. If most of the world used C# though, we'd look at C and complain how hard integration is. C makes ABI(Application Binary Interface) very easy, but the same does not apply to C++. C++'s polymorphism and classes make binary interfaces notably hard to predict and keep. .NET does allow hybrid executables(managed and unmanaged code), so in theory it should be possible to mix C# and C++ easily, but I confess I'm not sure how(separated assemblies with DLL should make this simple, but merging in a single executable requires methods I'm not fully familiar with).
|
|
« Last Edit: April 06, 2010, 01:46:42 pm by luiscubal »
|
Logged
|
|
|
|
|
Josh @ Dreamland
|
|
Reply #20 Posted on: April 06, 2010, 08:24:07 pm |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
"(such as register allocation)" I know Java lacks "unsigned," but I figure Java programmers would know about flags such as that and "register," which, as you say, 'allocates' a register. Not in Visual Studio, of course, as Microsoft shares the new philosophy that some day, computers will be able to run Windows 7 and Crisis! By that point in time, a typical programmer won't even need to know what a register is, or deal with nasty, old C++. Unless they intend to program for something other than the PC.
|
|
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
|
|
Josh @ Dreamland
|
|
Reply #23 Posted on: April 06, 2010, 09:42:03 pm |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
Rusky-- Yes, everyone that's done any real C knows that. What I was getting at is that Java likely lacks a way to specify which variables you would like to remain in the registers, as C/C++ does. I find it likely that Java lacks such a flag, seeing that it doesn't even have "unsigned."
|
|
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
luiscubal
|
|
Reply #24 Posted on: April 07, 2010, 06:22:02 am |
|
|
Joined: Jun 2009
Posts: 452
|
C#, however, has uint(and the equivalent for other types). "register" in C is a suggestion, never an order. You can have 50 variables in "register" in a processor with less than 50 registers. Because software is not frozen in time, its complexity increases over time(think browsers and HTML5, for instance). A good language is essential for maintainability reasons. C# and Java aim to simplify software so we can solve our problems instead of reinventing the wheel or have to deal with the language's problems like in C. The big API is part of that simplification.
The size of modern disks(several GB, maybe TB, and going up) means that, proportionally, the size of these APIs is perfectly reasonable(also, the .NET 4.0 installer is smaller than reaching its peak with 3.5)
|
|
|
Logged
|
|
|
|
Josh @ Dreamland
|
|
Reply #25 Posted on: April 07, 2010, 07:50:00 am |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
Ah. Disk size. Now fix my 30 dollar / mo 100 KB / sec internet connection. Also, I'm sure Australians aren't happy, considering their bandwidth usage is metered. They are capped in speed if they go over a certain limit.
|
|
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
score_under
|
|
Reply #26 Posted on: April 07, 2010, 09:18:15 am |
|
|
Joined: Aug 2008
Posts: 308
|
While Java and C# have bigger runtimes, they are not necessarily bloated Just big-boned, eh? Different computers have different hardware. Some processor-specific optimizations fail when you switch computers.
Yes, there are processor-specific optimizations, but then there are the optimizations that actually matter: common-sense optimizations. At one point in the DirectX 9 code, it uses this gem: add esp,0x10 mov esp,ebp Now, not only does that not use the shorter "leave" command, but it performs arithmetic and then just deletes the result! Any good optimizer could spot that right away. Also, on prediction of C and Java, consider this code:
//C++ if (x != NULL) x->someField = 2;
//Java if (x != null) x.someField = 2;
In Java, I can predict that someField of x will become 2. In C, I can predict nothing. In spite of the check, the application could still crash(segfault) if, for instance, x was free()d. Anyone who doesn't set a variable to NULL after freeing, if other functions are still using that variable, is really lacking foresight. As I see that, you're telling the computer to check if a variable equals zero, and if not then attempt to access memory a few bytes after where it points to if it doesn't. "x" is an abstraction, it doesn't exist. If you take away the foundations behind this abstraction, it's no surprise that it no longer works. The behaviour is perfectly predictable. When I write code in C, the spec states what happens. Ok, that's predict. But - guess what? - the same applies to Java. If nothing else, Java is MORE predictable than C because there is less *undefined behavior*(which C has plenty). OK, give me an example of undefined behaviour. I'd be happy for it. So, I said it and I'll say it again - as a language, C is great for low-level tasks. For high-level tasks, it is basically the same as Brainfuck(where everything is technically possible, just like in C). Have you actually written in brainfuck? I'd like to see you create a window with it. You're complaining that Java/C# are too high-level when it's their greatest advantage. This is not 1970 anymore. Most tasks no longer require such low-level tools. You can theoretically dig a 100km-wide hole, but nobody does it. The right tools for the right job. Possibility is irrelevant. What matters is viability. I don't care that it's not 1970 any more. Have you noticed that as hardware gets faster, software is staying the same? Ever wondered why? It's because of that mindset, "The technology nowadays can take it, I can afford a little slack". EDIT: Just found this gem in Wikipedia:
Ngen pre-compiles (or "pre-jits") bytecode in a Common Intermediate Language image into machine native code. As a result, no runtime compilation is needed. .NET framework 2.0 shipped with Visual Studio 2005 runs Ngen on all of the Microsoft library DLLs right after the installation. So it appears that even your beloved .NET DLLs are compiled. Worse - they combine the optimization advantages of JIT with the minimum startup delay of AOT!
I was complaining against the applications themselves. Also, I checked my .NET DLLs in Olly and most of it is still .NET, not native. There was a time where people said C was too slow that it was unusable.(asm programmers)
C programs generate about the same amount of instructions per function as someone with about average skills in ASM. It's because of that amazing thing called the "optimizer". Optimizers have been evolving, they haven't remained the same throughout the time. In fact, GCC's -O3 option is great at optimization. You should try it sometime. [For the record, I do program in ASM too]
|
|
|
Logged
|
|
|
|
luiscubal
|
|
Reply #27 Posted on: April 07, 2010, 09:34:25 am |
|
|
Joined: Jun 2009
Posts: 452
|
Ask Google for help. They're trying to bring 1Gb/s internet to the world. Now, think of the effect THAT has on the competition(hint: it might convince them to improve their services) But yes, I'll take that as a legitimate problem. However, I think .NET already comes with most Windows copies. As people replace their computers, they also get .NET along with it.
Last time I checked, DirectX was C/C++, so you hit your own language. Bloated != Useful. Who says they didn't? The fact is, in C(and not only in C), you can have multiple variables pointing to the same memory location. This problem does not happen with garbage collectors. In C, it happens pretty often, otherwise no programmer would know what "segmentation fault" means.
You want C undefined behavior? This, for instance:
int x[3]; int y = 0; x[y] = y++;
Different compilers may give different results. In fact, the same compiler may give different results for that same code.
|
|
|
Logged
|
|
|
|
retep998
|
|
Reply #28 Posted on: April 07, 2010, 09:42:57 am |
|
|
Location: Where else? Joined: Jan 2010
Posts: 248
|
You want C undefined behavior? This, for instance:
int x[3]; int y = 0; x[y] = y++;
Different compilers may give different results. In fact, the same compiler may give different results for that same code.
An array with a size of 3 is created called x but nothing is initialized to it. y is set to 0 the first element of x is set to 0, and then y becomes 1 for the next statement. end result: x = {0,?,?} y = 1 replace ? with whatever random garbage is still in the ram from before. there is nothing undefined about this code.
|
|
« Last Edit: April 07, 2010, 09:45:20 am by retep998 »
|
Logged
|
|
|
|
RetroX
|
|
Reply #29 Posted on: April 07, 2010, 10:30:53 am |
|
|
Master of all things Linux
Location: US Joined: Apr 2008
Posts: 1055
|
Different computers have different hardware. Some processor-specific optimizations fail when you switch computers. Also, on prediction of C and Java, consider this code:
//C++ if (x != NULL) x->someField = 2;
//Java if (x != null) x.someField = 2;
In Java, I can predict that someField of x will become 2. In C, I can predict nothing. In spite of the check, the application could still crash(segfault) if, for instance, x was free()d.
Well, yeah. If you deleted it, that's your fault. If it was deleted because it was a local variable, then you didn't use the -Wall flag (which, informs you of that).
|
|
|
Logged
|
My Box: Phenom II 3.4GHz X4 | ASUS ATI RadeonHD 5770, 1GB GDDR5 RAM | 1x4GB DDR3 SRAM | Arch Linux, x86_64 (Cube) / Windows 7 x64 (Blob)Why do all the pro-Microsoft people have troll avatars?
|
|
|
|