The number one reason current browsers are implemented in C++ is momentum. A browser has a lot of parts that do a lot of things; they're big code bases.
JIT compilation technology on the JVM (and elsewhere) these days is pulling within 20-50% of static C/C++ code.
If you were coding from scratch these days, would you start with C/C++? I doubt it, especially when you know you can get most of the same performance with other platforms.
By far the most important reason to choose a modern VM environment is security. Except in a vanishingly small number of cases, everything should always be bounds checked. The "native" part of a browser should be as small as possible, with a highly constrained and thoroughly checked API. Take away manual memory allocation and use after free goes away. Take away pointers and buffer overflows go away. You want as much of the browser code as possible to be running in a managed environment.
In my opinion every line of native code carries risks that don't exist in managed environments. Yes, properly written C code won't exhibit those problems -- but it seems to be extraordinarily difficult to do that. Security flaws are still being found in browsers, decades later.
And yes, security flaws exist in systems like the JVM. Those mostly come from native code as well, but some of them are because of the design. The JVM's "native part" is just too big. Too much is done there that doesn't need to be.
With a massive native code base it's just a huge problem to verify everything.
So Rust and Go are quite interesting. It's critically important that these languages remove "unsafe" features from something like C/C++, and lose almost nothing in the process.
And around the corner, environments like the JVM can auto-vectorize on the fly (http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7116452), knocking down yet another performance-parity barrier.
Before the inevitable "memory is cheap" argument is made, I'd rather have my client app be a good neighbor. Having a GC'd process on a client munch through memory like it's infinite is just bad manners and makes some bad assumptions. (On the flip side, a GC'd process that tries to be a good neighbor by freeing memory aggressively becomes a bad neighbor in terms of CPU time, which has additional consequences in terms of battery life.) The JVM, for example, tends to only run its GC when it needs to. It is a horrible neighbor in this respect because it just takes all the memory it needs and only runs its GC when it really, really has to. This is one of the reasons it's relatively fast, but as a consequence puts a lot of pressure on the system. In such a scenario it's possible other processes will OOM and be killed, or the system will start swapping memory pages, or other processes will have to run their GC more aggressively (as V8 does in low memory conditions) which puts even more pressure on the system. All this adds up to very selfish apps that bog down a system and can become virtually unusable. These selfish apps are also unsuitable for use in poorer parts of the world where incomes are lower and additional memory is potentially unaffordable.
I think it's probably okay to take the attitude that memory is cheap when you control the environment and you're paying for the memory, but in any other circumstance, shipping software that gluttonously gobbles memory is probably unacceptable and the #1 reason why C++ makes good sense as a language choice for writing a browser.
Shows how dependent on GC a large part of the community of developers have become - they are incapable of imagining a world without it.
(PS: I am amused when people mention that being 20-50% slower is described as fixing the performance gap.)
Cost of GC doesn't bother me.
Java's basic overhead for all data structures does.
Class String is a mistake. Better to have string scalars compiled down to char[], avoiding the class wrapper.
Massive overuse of HashMaps by most frameworks is huge drag too. Using typed collections (vs generics) like Trove helps quite a bit.
Our study group had a really good session on optimizing memory usage. Sorry, I can't quickly find the slidedeck we used. I used jamm to profile various strategies. Super fun.
I recently saw something in the newsfeed about JVM and optimal memory usage. Bit packing, word boundaries, ordering, etc. (It's more low level than I typically work, so I didn't bookmark it, sorry.)
What's a "stop the world GC"? I joke, of course, but I really haven't seen anything like that in a long, long time.
You're right about memory, but you're wrong when you propose C++ as a solution. C++ doesn't solve any of the problems you outlined. You can implement a solution to those problems in C++. A C++ program doesn't come with an inherent advantage in memory handling. Many of the same techniques (creating and managing pools of memory) can and are being done in applications (like Cassandra) on the JVM (off-heap memory).
What you're really deciding is whether you want to solve those problems in a VM, or solve them at the application level.
Garbage collectors give you two things -- a reliability backstop, and (when you take pointers away) increased security. The behavior of GC is something that can be tuned (often dynamically) for a particular environment.
I do, I like writing C++. The toolchains and infrastructure around it support really concise clean code since C++11.
I wouldn't probably want to do job-work with it, because it is easy to fuck up C++ (ie, the unsafe features) and trying to debug someone else's incompetence is a pain in the butt.
But I really like qt / kde and its support libraries and if you use a modern IDE, at least cmake-quality build systems, a memory profiler + debugger, and the modern language and syntax, it isn't any harder than Java or C#. I'd say its easier, lambdas and global scope let you do non-OO when it is appropriate.
Though I'd rather have Rust / its successor where you get something like C++-- where you add the good stuff (smart pointers, lambdas, generics) and remove the bad stuff (point mangling, ugly syntax, unexpected behavior, the horrible char/string format the standard uses, textual inclusion).
D is close, but since the entire std depends on garbage collection and it uses a runtime to enable mixins and other fancy features it isn't a drop in replacement. You need deterministic compile time assembly generation that does the minimum magic behind the scenes. You don't want the compiler to hide anything, but you also want it to present everything intuitively with a bend towards naturally promoting best practices, rather than crazy hacks in the C++ world like #ifdef <this header> etc #endif, d pointers, and its ilk.
I think that is actually the flaw in the Rusts / Gos / etc. When you put in garbage collection, mixins (or other code generation at runtime) you obfuscate the implementation which instantly makes it unsuitable for a lot of the reasons you use native code in the first place. The processor pipelines and assembly architectures themselves are already vague and unintuitive enough, throwing on language runtime features that you have to debug make it a much more difficult proposition.
I think inheritance is basically the limit of how much behind the scenes magic you can do (complexity wise) and still expect people to use it like its just a fancy assembly. It is easy to understand and debug vtables - it is much less easy to debug the generational shifting aspects of a good GC. It is even harder to debug the code generator making your runtime injected code. Those kinds of things make great libraries to link in knowing they aren't in the base language and aren't cluttering up your execution space with pervasive hooks everywhere to support a "clean" language syntax. Yeah, it means using a gc in C++ requires you to write things like gc::new(<construct object here>) when you want to construct it, and the gc itself requires an initializer (ie, in main, gc::start();) since C++ doesn't have autorun at start (which is good, in my book, it means the code running under the hood is only the code you say to run).
There's a reason your OS, your browser, your shell, your word processor, etc. are written in C and or C++ not to mention your JVM, python, perl, your favorite libraries, etc. It's not "momentum", it's "track record". Yes, you can shoot yourself in the foot with C/C++. Experts know this and manage not to maim themselves.
Java has improved ... a lot ... no doubt but the " 20-50%" is a tad hyperbolic. Yes, repeatedly calling the same function (who's internals are in C) with Java sometimes you can get to with 20%. And , of course, carefully crafted java routines can beat naive, sloppy C sometimes.
Back in the day, Java proponents promised us the Javagator [ http://www.wired.com/science/discoveries/news/1998/04/11458 ].
Don't hold your breath for a competitive Java browser. The speed and small foot print of C/C++ will continue to be edge giving it almost all the market share.
In C/C++ you have the option of not performing those kinds of checks to get speed. In a secure browser, you don't want to take that risk unless it's absolutely necessary.
I'm just kidding. I found after I upgraded from IE 7/8 (only had for testing) that 9 was pretty usable (haven't used past that).
Just out of curiosity though...depending on where it slowed down would people notice? If it still displayed as quickly but was slower to startup (or other examples).
I admit I don't know much about how browsers actually work (I am assuming it is more than just displaying html).
I have no idea why people keep bringing up Go as a C++ replacement language. I feel any C/C++ programmers that see Go suitable for their needs, would have already moved on to Java or C#.
Can anybody explain to me what makes Go favorable to a C++ programmer?
So it is possible that at some point other languages than C/C++ will be the languages of choice for large projects. But frankly I think that these will not be GC languages, but languages were you get the GC somehow from the paradigm. ( I am currently thinking of Haskell. Functional languages can do really interesting things with GC, since all their data is local. )
Parallelism may be the key to disruption here however; if a new browser can scale better to the multi-core present and future it may be worth taking a small hit over C++ in the sequential case. That's Servo's bet (although Rust strives for C++-level performance even in the single-threaded case).
How do people writing games in Java or C# deal with this? Gaming is an area where people expect smooth, high speed performance.
Short, mean answer: poorly.
Longer answer: they sacrifice the benefits of managed languages. They forego immutability and controllable object lifetimes for the use of object pooling to prevent the garbage collector from going nuts. And many still target 30fps in order to minimize the effects of variable latency.
I used to do this; I'm porting my stuff from XNA/MonoGame to my own OpenGL/GLFW/OpenAL engine in C++ because I grew unsatisfied with the performance and limitations inherent in the process. Many of the biggest benefits of managed languages are blunted with games in other ways, too. The CLR, for example, should be a huge boon for scripting--the DLR is a fantastic concept, for example. But dynamic code requires codegen, and System.Dynamic doesn't work in Xamarin's iOS product. So if you want to bring a game with scripting from Windows/OS X to iOS, you're boned. (Java has the same problems; Groovy, while a great scripting language, doesn't run on Dalvik or on IKVM-over-MonoTouch. Rhino's LiveConnect doesn't work there either.)
On the other hand, I use AngelScript and expose C++ objects and methods to it, computed statically at runtime but executable via interpreted scripts, for the best of both worlds without breaking my back to do it. Memory management just isn't that hard and the performance and compatibility of native code just can't be touched right now.
And even still, it often becomes a problem. Generally it's solved by being very careful with object allocation as to not require GC during gameplay. Or some other trick to force GC to take less time than budgeted.
Also keep in mind, a lot of games are designed to run much closer to 30 FPS these days. Which gives you a lot more time to deal with GC.
A browser that breaks on non-standard markup is worse than useless. Legacy compat is so critical and so complex that a rewrite is just not an option. Lots of money and time is invested in battle-tested security etc, you can't just throw that investment away. Again, like how Facebook is still written in PHP.
This isn't something quite as self-evident as you make it.
No way. You'd be laughed out of the room. How exactly would you get a radical expansion of the attack surface past a security audit?
You might do it in a game, where security is (usually) not a primary concern.
Anyone who would sacrifice browser security for a 25% increase in performance is a fool. Browsers need to be secure, and then performance needs to be "good enough".
We do it all the time.
Do most people care about that, though? Like, go to a page that demonstrates browser-benchmarks, then uninstalling their current browser, downloading the best one and installing it? Or are the browser they got "bundled with the OS" fast enough for them? (not to mention exporting and importing all their bookmarks.) Maybe I've been spoiled by having fast browsers, but I can imagine that I could live with that, if I gained other benefits. Most of the websites I read are either very "static" pages for mostly reading stuff, or videos. I am pretty content as long as webpages load in around one second (I can probably live with more than that too) and my videos buffer at a respectable rate.
If I got a browser that was 25% slower, but on the other hand was very much less prone to buggy behaviour, then that sounds like a great deal to me as a user. Chrome is annoying me right now because of the relatively recent behaviour of freezing the UI-frame when I make a new tab: I can type in text but it's effectively hidden to me, and I only get to press enter and see what I wrote after up Five seconds. Another problem (very common in Chromium) is the whole webpage being unresponsive until the whole page is loaded, instead of loading stuff like text and letting me navigate the loaded stuff. If these things could be actually fixed for me, the lazy user (ie without me changing browser or diddling around with stuff that I shouldn't need to diddle around with in order to have a performant browser), then that sounds like a good deal to me.
Developers should be language/technology agnostic and just use the right tool for a given problem/solution, the same way you use a screwdriver for screws and a fork to eat..
The stackexchange commenter moans about graphics performance in Java. I helped write the Magician OpenGL bindings for Java in the '90s (the Java API side was all me, which Sven of JOGL basically copied). My VRML browser was just as fast (fps) as the available VRML browsers written in C/C++. With JDK 1.1.
Nowadays, Java and OpenGL go together like peas and carrots. Exhibit A is MineCraft.
A good buddy of mine does all his projects in Java and OpenGL. The latest is the awesome 2D skeletal animator called Spine at http://esotericsoftware.com. I couldn't imagine him doing it on top of any other stack.
With respect, I find your claims dubious. I would certainly buy that your top framerate was competitive. I also expect that your framerate was significantly more stuttery and inconsistent due to garbage collection (or else written in such a devolved form of Java that you really might as well write C++ anyway).
The problem is not Java's execution speed. It's that garbage collection is the death of responsiveness.
> Nowadays, Java and OpenGL go together like peas and carrots. Exhibit A is MineCraft.
Minecraft's performance characteristics are pretty bad for the fairly trivial rendering work being done. (It's improved, but it's still not great.) And writing code with LWJGL/JOAL is gross relative to similar code in C++--I have done both. You don't get anything for tying yourself to the JVM except, in a weird and mostly self-destructive way, the 'freedom' from understanding your object lifetimes and deterministic destruction.
I've used libgdx and XNA/MonoGame extensively and have gone back to C++ because both are fairly limited in their usefulness. libgdx helps by hiding a lot of nasty API issues--and Mario and company are super good at what they do--but what it gives you is generally taken away by the limitations of the JVM in a client context (limited platform support, the infuriating Dalvik/Hotspot divide, That Frigging GC Again...). Writing up some pretty minor glue code between windowing, input, audio, and graphics isn't that bad. And, perhaps more importantly, you'll actually understand how it works. (I've spent the week fighting with OpenAL. I'm glad I did. I've learned a lot and can recognize the failure cases and can do something about them.)
> A good buddy of mine does all his projects in Java and OpenGL. The latest is the awesome 2D skeletal animator called Spine at http://esotericsoftware.com. I couldn't imagine him doing it on top of any other stack.
Spine's pretty impressive, but there's not much in it you couldn't do with ease with Cocoa/Obj-C[++] or Qt or even WPF and .NET. It's also a misleading example, though, because tooling generally has much looser latency requirements than user software and so the severe weaknesses of JVM client applications are less readily apparent than in an application that needs to hit 60fps all day every day.
Consider, not just PC based browsers, but the one on your phone. Every JIT compile costs watts, not just time. There's a relatively large push to go back to C++ because of this (power usage). 20% reduced performance may not be noticable as far as user interaction goes, but it is sure noticed in terms of "my battery just died!".
It's nice to have a common code base. C++ across multiple platforms reduces my cost, even if I have to pay for good programmer that understand the use of things like smart pointers.
Very little mobile phone software these days is written in cross platform C++, of that it's mostly games. Most iPhone software is still written in Objective C, most Android software is still written in Java. For cross platform code, I'd say Xamarin or Unity C#, or Adobe's product line both are still beating out C++, even counting the games.
Chrome is about 40% C++, and is now the default browser for android.
C#/Xamarin would probably be what I'd standardize on if going for a true cross platform non-game app. Javascript/Unity3D or C+/Unity3D would probably be what I standardized on for games, with Futile being looked at hard for 2D games.
Companies with a huge existing codebase (e.g. EA) likely find porting an existent engine cheaper than writing a new one, and will of course stick with their historical C++
If claims made by certain language X apologists are to be believed, one can infer that language X should permit developing a web browser in shorter time than C++, with performance within say 20% of C++ (or even superior to C++, depending on X and the apologist), with fewer bugs, and with a more maintainable codebase as the result. Actually delivering such a web browser would be a rather more convincing argument than empty talk or even glorified Fibonacci programs. Hence, I'm very much looking forward to future progress by the Rust guys.
Mozilla tried the low-level guts/high-level UI approach anyway, using JavaScript because they had to implement an engine for it anyway. But it took them a few tries to really get it right, and its false starts in this category remain infamous to this day. The others stuck with C/C++ for everything because it's what worked at the time, and continue because it works for them.
Mozilla's at it again with Rust, though, and that looks like it could be an interesting project.
Why an OO language? Well, while OO is overused, a HTML document looks a lot like a bunch of objects, doesn't it?