Why are most browsers developed in C++?
programmers.stackexchange.com
programmers.stackexchange.com
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.
Unity manages to do quite a bit with the CLR on a cross-platform basis, and that looks like Javascript to me.
Horrors! AngelScript has Garbage Collection! But since it didn't come from the JVM, I guess it's OK.
http://www.angelcode.com/angelscript/sdk/docs/manual/doc_mem...
> Memory management just isn't that hard
Every victim of a use-after-free just cried out in anguish. Your world weeps at 60 fps.
Keep in mind the original question: What's a good language for implementing a browser? The number one requirement for a browser today is not performance. It is security. A decade of effort has been put into the major browsing engines to snatch pseudo-victory from the clutches of determined hackers. A great deal of that effort has been necessary because of the desire for "speed", and the fallibility of those who believe memory management "just isn't that hard".
I guess that's why libgdx very recently added pooling, right? And (OK, it's Dalvik, but still) why Android uses view recycling all over the place? Why recommended practice for ListView is to re-use existing objects whenever possible?
I'm not pulling the use of pooling out of my ass here. This is what you do for high-performance managed stuff, in games and otherwise. Everybody I've ever worked with, and I've worked with some pretty heavy hitters (some of my former coworkers at TripAdvisor are insanely plugged into the Way Of The JVM), has kept pooling in the toolbox for latency-sensitive problems.
> Unity manages to do quite a bit with the CLR on a cross-platform basis, and that looks like Javascript to me.
Well, for one, it's not. It's statically typed sort-of-JScript. It bears little relation to JavaScript; it was originally called UnityScript and the name was changed largely for buzzword bingo purposes. (It's really very frustrating when working in Unity, both because it's not real JavaScript but doesn't play nicely with Boo and C# scripts a lot of the time.)
Unity also has notable performance problems for nontrivial scenes due about 50/50 to expensive creation on the front end and garbage collection on the back end. One of the most popular Asset Store items is--wait for it--an object pooling system.
> Horrors! AngelScript has Garbage Collection! But since it didn't come from the JVM, I guess it's OK.
It does, but only if you're allocating within it. I literally never allocate non-stack data in it. I use it as a logical glue layer within my application, which is not garbage collected.
> Every victim of a use-after-free just cried out in anguish. Your world weeps at 60 fps.
I literally can't remember the last time I hit a use-after-free in my own code. If you understand your object lifetimes, RAII will usually (almost always?) put you in the right place. In the worst of cases, where you've found yourself in a thoroughly opaque situation and can bear the perf hit, you have tools like boost::shared_ptr (though in my current project I don't use it anywhere).
It's certainly possible to make mistakes, but it is easier to do the right thing than most managed-languages people are willing to admit. I used to be one. It's why I was pretty terrified of working in C++ for so long. As it happens, I think former-me was pretty wrong about that.
> What's a good language for implementing a browser? The number one requirement for a browser today is not performance. It is security.
I'm of two minds about this. Sure, security is a critical concern. But user experience isn't to be ignored, and I really do feel that user-detectible pauses are to be avoided at all costs. Writing better native code is, to me, a more feasible option than an imperceptibly fast general-purpose garbage collector.
(As an example, I grow frustrated when scrolling a big list on my Nexus 4 when I can watch the scrolling get stuttery. In my experience, it's almost always due to someone not following best practices and re-allocating instead of re-using existing objects.)
But, all things considered I'd rather Somebody Else (because Somebody Else makes browsers, I don't) spend developer time making a fast system secure rather than running a slightly more secure system up against the hard walls imposed by any managed language one would care to name.
No, I don't think they're straightforward to avoid.
I think it seems straightforward to avoid memory lifecycle bugs because it's straightforward to avoid them under normal operating conditions. But attackers don't honor normal conditions; they deliberately force programs into states where events are happening in unexpected ordering and frequency.
I don't even know where to begin with the idea that it's acceptable to sacrifice a couple memory corruption vulnerabilities in the service of a faster browser.
Fair enough, and you certainly have more experience on the topic than I do. Thanks for the explanation.
One quibble though, and maybe it was poor phrasing on my part:
> I don't even know where to begin with the idea that it's acceptable to sacrifice a couple memory corruption vulnerabilities in the service of a faster browser.
It's not really an either/or though, right? I mean, you can protect against some forms of attacks through a managed environment (though the environment itself adds its own attack surface). But you trade performance to get it. A managed language isn't going to solve all your problems, and it is going to mess with your performance in inconsistent and essentially intractable ways. I'm not saying "throw in a couple memory corruption vulnerabilities if it'll make it faster", I'm saying that you can fix memory corruption vulnerabilities. You can't fix inherently slow.
How/where does immutability come into play here? Isn't it orthogonal to GC? Genuine question.
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.
An object pool can also be implemented without unsafe bulding blocks or other language support, as a pool of objects that are manually recycled after the pool lifetime is up. Then a bug could let you confuse a previous generation object witha current-gen one, but would not break memory-safety either.
Deleted comment
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.
Deleted comment
Hardware assisted GC isn't free. It comes at a large cost of silicon* and power. And makes a lot of assumptions and puts a lot of restrictions on your GC. And it still doesn't solve the caching problems related to automatic memory management.
* The silicon has to come out of the die budget somewhere. likely decreasing performance on other operations. Or removing other special purpose instructions altogether (SIMD?)
Oh dear.
Yes, it is unfortunate we can't use those languages and achieve the same performance as manual memory management in C/C++.
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.
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.
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.)
So memory right now is important. And browsers are using way too much already.
[0] http://blog.mozilla.org/nnethercote/2011/11/01/spidermonkey-...
Otherwise, C++ is really our only choice for a mature, modern language without GC.
I seriously think that anyone who finds themselves reaching for C++ to solve a task should try Ada instead. The semantics of their code will be clearer and their code will be more readable, therefore maintainable.
I'm not sure anybody would use Objective-C if it weren't for Apple, any more than people would choose to use JavaScript if it weren't for it being the only language available in the browser.
It's a bit of a chicken and egg problem, but the one thing you really need for a successful OSS project are developers. Do any of the Object Pascal implementations actually have a community?
A codebase as large as a browser written in C would be a horrible, unmaintainable mess IHMO.
[-1] http://benchmarksgame.alioth.debian.org/u32/ada.php
[0] http://www.amazon.com/s/ref=nb_sb_noss_1?url=search-alias%3D...
Granted, the sort of person who is likely to use Ada is not a l33t hax0r, but someone who's been around the block a few times on major engineering projects. Still, GNAT has bindings to the likes of Gtk and OpenGL, a direct result of increasing interest in Ada outside of critical systems engineering.
It's a bit of a chicken and egg problem, but the one thing you really need for a successful OSS project are developers. Do any of the Object Pascal implementations actually have a community?
FreePascal/Lazarus does. It's mainly Europeans (French and Germans primarily) who once did PC development with Turbo Pascal.
I'm not sure anybody would use Objective-C if it weren't for Apple, any more than people would choose to use JavaScript if it weren't for it being the only language available in the browser.
I would (and do). Its Smalltalk-based object system is much easier to wrangle than C++'s.
A codebase as large as a browser written in C would be a horrible, unmaintainable mess IHMO.
Yes, point against C. C++ has the advantage that it can turn even small codebases into horrible, unmaintainable messes. :) This is the reason why I converted an entire game engine to Objective-C.
> We find that an existing modern implementation of reference counting has an average 30% overhead compared to tracing, and that in combination, our optimizations are able to completely eliminate that overhead. This brings the performance of reference counting on par with that of a well tuned mark-sweep collector. [-3]
Even the best tuned mark and sweep GCs are a drag on performance.
> Reference counting is expensive - every time you manipulate pointers to an object you need to update and check the reference count. Pointer manipulation is frequent, so this slows your program and bloats the code size of compiled code. [-2]
> "Unfortunately, reference counting is expensive in both time and space". [-1]
Also, the slide entitled "Why reference counting is slow" in some recent lecture notes go into some detail. [0]
[-3] http://users.cecs.anu.edu.au/~steveb/downloads/pdf/rc-ismm-2...
[-2] http://ocaml.org/tutorials/garbage_collection.html
[-1] http://www.rtsj.org/RTJPP/errata.html
[0] http://cs.nyu.edu/courses/fall12/CSCI-GA.2110-001/lectures/G...
Please don't thoughtlessly replace pointers with shared_ptrs in an attempt to prevent memory leaks; shared_ptrs are not a panacea nor are they without costs:
-a circular linked structure of shared_ptrs will cause a memory leak (you'll need some logical complication to break the circle, e.g. using a weak_ptr)
-"shared ownership objects" tend to stay "live" for longer than scoped objects (thus causing higher average resource usage)
-shared pointers in a multi-threaded environment can be expensive (because of the need to avoid data races on the use count)
-a destructor for a shared object does not execute at a predictable time, and the algorithms/logic for the update of any shared object is easier to get wrong than for an object that's not shared
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.)
I generally work on the JVM and I do enjoy it, but if you're looking for rock-solid 60fps-all-day-every-day, the cost of GC without question should bother you a great deal.
I would never implement a browser in a managed language and I would do everything in my power to avoid gating rendering on the completion of execution of its scripting system for similar reasons.
Rock-solid FPS doesn't preclude GC. What it requires is a separate rendering layer that isn't subject to any GC pauses (or a game-like rendering loop that's always on time). The managed code manipulates the declarative level of the animations, and the low level handles the frame-by-frame details.
On relatively small heap sizes (under a GB) GC on recent PC hardware usually fits into the equivalent of a single frame -- under 30 milliseconds. Concurrent collectors would rarely need anything more than that, and wouldn't stop the world in any case.
The question here is, can you build a stable high performance rendering system on the JVM? If not, what would you have to change to be able to do that?
Correctly constructed you wouldn't have to change much. And JMonkeyEngine shows you can do a lot with what's there right now. There are some excellent discussions on its site on the topic of GC.
I don't think this is true. It's considerably more than rendering--it's reactivity. You need to handle audio streaming without pause, be able to process and dispatch input events seamlessly as well (I don't even know how you'd do this), so on and so forth. You'll essentially need to pull everything except actor logic out of the Java layer. Even some of that will be latency-constrained.
If anything, I think Unity is on the right path here: embed a sufficiently optimized virtual machine inside an engine that does all the hard work. But Unity still suffers from serious perf issues with nontrivial scenes. Like I said in another reply to you, object pooling is still heavily used in Unity because of the costs of object creation and destruction.
> On relatively small heap sizes (under a GB) GC on recent PC hardware usually fits into the equivalent of a single frame -- under 30 milliseconds. Concurrent collectors would rarely need anything more than that, and wouldn't stop the world in any case.
Sure, but that's too slow. The human eye can easily, easily, detect a dropped frame. Concurrent collectors (you mean Azul and friends?) are a possibility but we'd need a portable one that's freely licensed. If you've got one in your back pocket...gimme. =)
> The question here is, can you build a stable high performance rendering system on the JVM? If not, what would you have to change to be able to do that?
This is a tricky question. My instant reaction--"you can't"--feels right for the current state of the JVM. I do think something like Azul or another fully concurrent collector helps. But even then the JVM just has its limitations. Like, you're going to blow up your cache iterating a list of whatever your "GLbuffer" analogues are, unless you decompose all your objects. In most games way more of your code ends up being engine code than game logic code and so you're kind of hosing the main reason to use the JVM: a mostly-clean object-based system.
At that point, I'd just write C++ and embed a scripting language. (Recurring theme!)
> And JMonkeyEngine shows you can do a lot with what's there right now.
JMonkeyEngine is actually a major reason why I'm not using the JVM--if they can't get it good enough, I sure won't, right? IMO, you don't get enough from using the JVM (unless that's all you know, which'd just be sort of a shame) to make up for its limited platform reach and its perf issues. What you can do with it, right now, relative to just sucking it up and writing some C++ (and I do mean "sucking it up", I hate writing C++), just isn't enough.
No contest on your position regarding high fps and using a GC language like Java. I definitely don't have your experiences.
I equate VRML browsers with HTML browsers. General purpose, casual use, low cost of content production, etc. Just like with an HTML browser, even if you can make a fast twitch game with VRML, you probably shouldn't, for so many reasons.
My project was a virtual world construction kit based on a modular toy system. Think LegoCAD. At the time, VRML was ideal.
My last project was a now-defunct deformable-terrain world game[1], based on voxel fields and surface nets. We were running into problems with Lua's GC just on our actors, nothing else in the world. With the amount of data we were forced to push around, I can pretty confidently say that an all-managed environment would have killed us (because we tried it first in C# and it did).
[1] - An early video, before the team broke up: http://static.largerussiangames.com/voxels/videos/rigidbodie...
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.
Yes, it's easier to write safe applications in a managed language, but it comes at a performance price due to the GC.
It's far easier to write an app in C++ that performs well. There's no overhead of a virtual machine (there goes the safety...) and manual memory management tends to also yield better results in terms of footprint and CPU time when done properly. C++ gives you the tools to implement a fast process with a small memory footprint; managed languages do not unless they're using a null GC! C++ also gives you the tools tools to write a sloppy heap of shit, but then again, Java affords such a facility too!!
Garbage collection simply isn't free. Maintaining the lie that a system has infinite memory comes with a price.
I'm not making the point that GC is evil, and I write code in managed languages frequently, but I am making the point that it's really only appropriate for situations in which you're paying for the hardware, and using a managed language makes good business sense.
Actually, many modern GCs are still "stop the world" including many generational GCs. the alternative generally has overhead elsewhere that hurts performance. GC has a lot of tradeoffs.
> 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).
Sure, but it sure is a lot easier in C++ since the entire infrastructure doesn't assume GC is operating. I don't even know a way to reliably allocate a temporary object in Java that won't trigger GC I could guess some things that would probably cause the optimizer to allocate it on the stack, but that precludes having the temporary lifetime outlive the stack. (It must however be said, I'm not really a Java programmer)
> Garbage collectors give you two things -- ... and (when you take pointers away) increased security.
As you just said, increased security is from taking pointers away, which is completely orthogonal to GC.
That's not what he said. Removing pointer arithmetic [1] is part of getting memory safety, but not the entire story. Avoiding dangling references is another part of memory safety, and GC is one way to accomplish that; it's not orthogonal.
[1] You cannot actually eliminate pointers entirely; you can disguise them, but if you want a dynamic heap and not just static memory, you need to be able to reference memory within the heap. When people talk about eliminating pointers, they generally mean unsafe C-style pointers.
It's the removal of the `free` and `delete` semantics that avoid dangling references. Not GC. While GC posits a good alternative to many of these problems. GC doesn't actually help memory safety at all. Unless you consider memory leaks to be a matter of "memory safety".
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. )
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.
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.
Static scenes, simple eventing. Compile the screen graph to meshes, load textures, then move the camera around. No stutter.
The trick is to avoid the GC, not thrash the heap, don't create a lot of short-lived objects.
Implementing LOD would have sped up my browser quite a bit.
The other idea was to compile VRML's DEF prototypes to Java byte code, avoiding VRML engine overhead, in which case my Java would have smoked C/C++.
My conclusion was not that my stupid simple browser was amazing, but rather the "native" C/C++ implementations were terrible. By comparison, my browser was about 5 times faster than LiquidReality, another Java-based browser.
With judicious use of off-heap memory for regular structures it's simple to erase much of the crap in the heap, and reduce already-tiny GC times even further.
Never dropping a frame is another goal entirely, though, and for that I still believe you need a separated rendering/animation mechanism.
Also, when I said 'quite a bit', I was thinking about the data-plumbing logic --- not UI and WebKit logic. It doesn't really make sense to rewrite WebKit.
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++
Chrome is 100% C++. Did you ever sync its source code from the repo? (i wonder what the other 60% are in your opinion, Js?)
edit: to be fair there are a little of objective-c and java just to glue with mac/ios and android
The metric is probably off from the automated calculator.http://www.ohloh.net/p/chrome It's likely counting the .h files as C
also there are a lot of tools written in python(gyp, grit, ninja etc).. but this dont get into the executable or libraries.. so i would not count (at least in the perspective of this thread) as the chrome itself. since those tools are used in other projects as well and come only with the source code to build things (it would be like to count the gcc compiler as part of the source)
Can you envision an alternative for C++ with similar performance characteristics, if historical investment and reliance is taken out from the equation?
I can only think of something like Rust, because it allows such a fine-grained control over the platform which is essential for all sorts of low-level code which implement an abstraction, such as game engines.
Objective C shares many of the advantages of C/C++.
> I'd say Xamarin or Unity C#
Speaking of Unity, while much of the game specific code is written in C#. As far as CPU time, the vast majority of execution is spent in C++ code.
Similarly on the Web, there is more Javascript code that runs in the browser than browser code. But most of the CPU time is spent in Browser C++.
And much of the operating system specific code is written in C. I've always found this "My tight loop is in the language I like" argument a little weird.
I was simply saying that since we were talking about the performance of browsers (An application that pretty much is the tight loop) Bringing up examples of applications that are not in such a tight loop may not be the most relevant without also discussing where their "tight loop" is.
Does that perhaps clarify my comments?
Also, keep in mind that in a well designed system. The "tight loop" should be in application code. Not OS code. The OS should generally have a priority on latency and overhead over raw throughput.
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..
Why an OO language? Well, while OO is overused, a HTML document looks a lot like a bunch of objects, doesn't it?