HNHacker News
TopNewBestAskShowJobs

ootachi

1,513 karma · joined October 13, 2010

submissionscomments
ootachi··on Why You Should Be Excited About Garbage Collection in Ruby 2.0
Another point in favor of my theory ;)
ootachi··on Poll: What's Your Favorite Programming Language?
You're talking to Yehuda Katz here. Yes, he has worked with Firebug.
ootachi··on Why You Should Be Excited About Garbage Collection in Ruby 2.0
The standard state-of-the-art for garbage collection is two-space copying for the nursery, and mark-and-sweep for the tenured generation. That way you avoid copying the whole heap on every GC; you only get copying for the nursery. You may have a compaction pass for the tenured generation that runs very rarely (much more rarely than a regular minor or major GC). V8, Java, and OCaml all follow this model, and I believe .NET and Haskell do as well. Lua skips the generational part for simplicity's sake (as games care a lot more about latency than throughput); SpiderMonkey does too because Mozilla hasn't implemented generational GC yet.

If fork() performance is important to you, you probably don't want compaction for the tenured generation at all. That's totally fine; while fragmentation will accumulate over time, it's no worse than C++. You'll still have copying for the nursery, but the nursery fills up and gets recycled so often that the COW optimization isn't really helping you there anyhow.

ootachi··on Why You Should Be Excited About Garbage Collection in Ruby 2.0
I have a theory, which has so far held up [1], that every remotely popular language that needs automatic storage reclamation ends up growing a generational and incremental/concurrent collector, either in its main branch or in a fork [2]. It's just a matter of time. Efficient automatic storage reclamation is hard.

[1] Language developers sometimes claim they don't need it. I believe they're on the wrong side of history.

[2] Forks are common for this, and for good reason; often times languages that start with reference counting end up taking large dependencies on external libraries that manipulate reference counts (like Python with its Py_INCREF and Py_DECREF), at which point the language can't fully move to tracing GC without breaking its ecosystem.

ootachi··on Poll: What's Your Favorite Programming Language?
It changes all the time, and all languages have their merits and drawbacks. But I'd say Rust for now.
ootachi··on Is C++ the Language of the Future?
Yeah, atomic RC hurts a lot (5x-10x slower, based on the measurements I've seen -- Hans Boehm of Boehm GC fame did a presentation on this that you can find if you're interested). (This is a problem with Objective-C reference counting -- they use atomic ops for all reference counting I believe.) There's some work on mitigating its cost with per-thread reference counts arranged in a tree or whatever, but it's still tough.

The alternatives are either (a) avoiding shared state; (b) strong lifetime management such that you make sure one parent thread owns all of the data that its child threads are going to use; (c) concurrent GC; (d) pretending it's not a problem like Go does and doing stop-the-world GC.

ootachi··on Is C++ the Language of the Future?
Right, as soon as it goes out of scope. (Or when you call release to drop the last reference on it, if you aren't using ARC.)
ootachi··on Is C++ the Language of the Future?
Yes, Objective-C will reclaim your retained objects promptly (unless you use the deprecated Objective-C garbage collection, which few do and never worked on iOS).

The exception is the autorelease pool, which gets dumped at the end of every turn of the event loop. You can promote or demote objects from the autorelease pool at will.

Anyway, the biggest problems with Obj-C memory management are (a) you can't allocate objects on the stack, so you're forced into using the autorelease pool for stuff, and (b) you can promote or demote objects from the autorelease pool at will, which means that even the autorelease pool has to malloc, thus you don't get the nice benefits of super-cheap bump allocation that C++ arenas (or a generational GC's nursery) buy you.

ootachi··on Is C++ the Language of the Future?
Well, you have to make sure that you use atomic reference counting in this case. Using regular reference counting will lead to subtle and hard-to-diagnose bugs.

Also, to answer your query, Rust uses unique pointers (the equivalent of std::unique_ptr in C++0x) for inter-thread communication. When the unique pointer goes out of scope, its memory is immediately freed (since it was the only owner of the data). And since the data has only one owner, it's data-race-free.

ootachi··on Is C++ the Language of the Future?
No Scala or Rust? Especially Rust seems like it fits the author's wishlist.
ootachi··on Linux Creator Linus Torvalds Declined to Join Apple
That was a dumb decision on Linus' part. Apple is the future; Linux is the past.
ootachi··on Code iOS Apps in OCaml
OCaml is a highly underappreciated language. The biggest problem is the haphazard syntax, but if you can get over that, it's really a joy to use for application programming. You get the strongly-typed, type-inferred, functional aspects of Haskell, but without the drawbacks of laziness (for example, you can safely do IO outside the IO monad, and space leaks are less common) and with a simpler type system. There are no null pointers, and coupled with exhaustiveness checks in pattern matching, you frequently find that "if it compiles, it works". The compiler is a simple non-optimizing compiler, but it's more mature than, for example, that of Go (especially in the GC), so it beats Go in performance.
ootachi··on Chrome beats IE market share for one day
Google can't realistically push more people to use Google by default. Google search is a monopoly.

I believe it is fair to state, however, that one of the reasons that Chrome exists is that Google wants Google to be synonymous with the Web in the minds of consumers. When your browser is Google and your search engine is Google, the web to you is Google. This will dovetail quite nicely with all the other places they're trying to expand to once they manage to establish a dominant browser market share.

ootachi··on Chrome beats IE market share for one day
No, people are choosing Chrome over IE for home use. The trend is clear; Chrome is likely to achieve a crushingly dominant market share in a couple of years, or sooner.
ootachi··on "Lighten up"
On the contrary, this happens all the time in startups. Think about it: a lot of startups consist of early 20-something males running everything.
ootachi··on Looks Like Zynga Just Bought OMGPOP For $200 Million
Founders often don't have a choice as to whether to accept buyout offers. In the case of OMGPOP, which had received a ton of VC funding and struggled for years until finally finding some success, I can definitely see why VCs would want to force a sale. (In fact, I wouldn't be surprised if VCs generally think that "make games for iOS" is not a business model that is capable of the kind of returns they need anymore, and they want to avoid taking further risk on that model—hence they forced the sale.)
ootachi··on In-memory key-value store in C, Go and Python
Careful with that argument. The fast, easy, naïve implementation in Go is quite dangerous (not even memory safe), because he forgot to lock the map. Go made it easy to write an incorrect implementation of a key-value store...
ootachi··on In-memory key-value store in C, Go and Python
And in Go, they aren't running long enough to see the GC kick in. I suspect the overhead of GC will be significant without tuning.
ootachi··on In-memory key-value store in C, Go and Python
So much for CSP, if you're using threads and shared state.
ootachi··on In-memory key-value store in C, Go and Python
There is no default in C, beyond stdio. The C specification makes no reference to any I/O beyond stdio.

The author was being unfair to C. Use epoll or, better yet, libuv. libuv is a simple-to-use library.

ootachi··on How it feels when everyone you know gets laid off
Seesmic is dead? How come we aren't hearing about this?
ootachi··on How it feels when everyone you know gets laid off
The second dotcom bubble is bursting.
ootachi··on The death of Firefox
Reimplementing it would not be an option. Making WebKit the reference implementation would give Google and Apple such an enormous advantage in development cycles that any browser that didn't use it would be unable to compete. You'd be expelling everyone but Google and Apple from the W3C.

If WebKit becomes the standard, every user from now until forever will be using the same pile of C++ to browse. That may be fine to you; I personally don't think that WebKit is so good as to make it the gold standard for the Web. Imagine if that had happened with NCSA Mosaic...

ootachi··on Why I Don't Want to Learn Go
Go isn't failing. It's actually doing quite well. I disagree with the design and implementation of almost every part of the language, but credit where credit is due: Google has created a language that a lot of people like.
ootachi··on Why I Don't Want to Learn Go
It doesn't. Go provides stack allocation and heap allocation. Stack allocation is the default (except for some always-on-heap things), and stack allocation is silently converted to heap allocation when you take the address of an object.

Go's memory management story is basically the same as Java's with the "use escape analysis to place objects on the stack" flag enabled. (To be fair, there is one extra thing that Go provides: the ability to allocate objects inside other objects.)

ootachi··on Go is amazing, period.
"If data is on the stack, any references starting there disappear as soon as that stack frame is popped, so there's no lingering work for the GC to do"

You're only considering the sweep phase. Sweep is the easy part of tracing GC - you can always chuck sweep into a background thread. The mark phase is the problem. Marking always has to trace roots, including stack roots - that's how GC works. Tracing GC never traces dead objects.

You can reduce allocation pressure by using the stack, which will make the GC run less often, but my point is that when it does run you're no better off than Java, and quite a bit worse since Java's GC can run in parallel with the mutator and Go's can't.

"Your comments strongly imply that you have no practical experience with Go's GC. I suggest you stop claiming that it has certain performance characteristics or behaviours when you have not experienced it yourself."

I have experience with GC generally. There's nothing particularly special about Go's GC: it's a standard stop-the-world mark-and-sweep collector for a language that supports a limited form of stack allocation but generally uses heap allocation. The performance characteristics that this form of GC must have are well-known.

If you want data, look at the binary-trees benchmark: http://shootout.alioth.debian.org/u32/benchmark.php?test=all...

It's mostly a test of GC. Java's GC runs more often (thus the memory use is lower) and yet it's still 4x faster. This is because Java has a generational, concurrent-incremental collector.

ootachi··on Go is amazing, period.
C compilers can and do generate SSE. Programs do rely on this code generation for performance. They fall back on assembly when codegen fails. That doesn't mean that they aren't relying on the optimizations in other places.

And a huge amount of graphics processing is always done on the CPU. Unless you're using Direct2D or something, rasterization is always done there (and even if you're using Direct2D, a lot of rasterization is still done there).

ootachi··on Go is amazing, period.
Replace "PC" with "program". That's the key here.

Most of the code in any program is not performance critical. Yet the reason that this is the case is that most of the time of any program is spent in tight loops. Those tight loops are what must be optimized. And that is why performance-minded systems programmers use top-notch optimizing compilers.

The popular dynamic languages have gotten away with being relatively slow because programs written in them are either not CPU bound or spend most of their CPU time in C libraries. This works great for them -- dynamic languages are awesome! But the calculus changes when you're programming in a language that defines the entire stack. When there's no C-compiled code to fall back on, micro-optimizations start to matter.

ootachi··on Go is amazing, period.
Mutating a hash map in Java while another thread reads it won't cause bad things like:

(a) memory you don't have access to to be read;

(b) other threads to crash;

(c) the VM state to be corrupted;

(d) the GC to crash;

and so on. The Java world is still in a consistent state. In a security-oriented world, this is important.

To the reply: It's a bit pedantic for me to say this, I know, but that's still "a consistent state". Basically, a Java program can't do anything it wouldn't otherwise be able to do by modifying a hashmap concurrently. Java programs can go into infinite loops. They can't access uninitialized memory.

ootachi··on Go is amazing, period.
Go gives you slightly better control over allocation than Java (in that you have a choice to allocate on the stack and inside other data structures -- but keep in mind that escape analysis can give you this too, see the optimizations in the Jikes RVM). However, in Go, you still have no choice but to allocate on the heap in many instances (for example, when returning a data structure from a function, or when using maps, etc.) You're taking a big bet that programs will be able to use the stack and manually use free lists or whatever (which you can still do in Java!), and that the slow performance of the GC won't be a problem. I wouldn't take that bet.

Besides, once you have a stop-the-world multithreaded GC, it has to trace all the roots in the program for correctness. There's no way around that. At that point having all the data on the stack doesn't help you (except for cache locality, but Java's GC already does that via the nursery and copying during major collections). You must still trace every pointer in the object graph, while keeping all threads suspended. You can run the GC less often, but that's not much of a help when interactive performance is at stake. iOS feels so great because the UI is always running at 60 frames per second. Stop-the-world GC can't do that.

← PreviousPage 2 of 16Next →