Compared to your grand-daddy's GC? Obviously yes. But no GC language
has yet prevailed against C in benchmarks.
I don't have any statistics, but I'm not so sure of that. At least, as I
said, depending on the use case. Heavily multi-threaded and dynamic
memory intensive code takes a huge hit in locking for every malloc, and
garbage collectors have a lot to gain by managing their collection in
batches. I'm fairly certain that I can find benchmarks to the contrary.
You're right, I've read something similar: the GC-featured performed better
because the multi-thread/manual memory management was beyond human
capabilities.
In these situations, it's hard to get things right for a start, and one
may argue that the programmer has simply shot himself in the foot; heavy
use of threads and dynamic allocation doesn't look like a "suckless"
implementation.
Beyond that, there are cases like the Dis vm, which uses ref counting
with a low priority, real-time, non-locking GC to clean up cycles.
Automatic ref counting has no performance drawbacks over manual ref
counting, and the GC has virtually no impact on performance otherwise.
This must be taken with a grain of salt. A measured performance impact of
the GC of 2% in a VM-based system is one thing. Given that VMs are
generally
an order of magnitude slower than native code, the measured performance
impact of the same GC in a native code program could raise to 20%.
Interfaces and packages are free, as far as performance is concerned,
though implementations may vary.
It seems to me that there's virtual tables behind interfaces, which
means one level of indirection.
It may be cheap compared to the provided facility, but it's not free.
That's an implementation detail. In principal, they're not necessary.
And it very much depends on what you're comparing them to. It's fairly
common for C code to provide structs of function pointers, and this is
no different. Namespaces require nothing more than symbol mangling.
You're right, it's not more expensive than function pointers.
C strings are slow when you need to get their length.
It's not a win-all situation. Immutable strings may be more expensive
in some use cases.
Furthermore, they either have to convert back to zero-terminated
strings when passing them to libs, or use the trick of appending
("quand même") a zero byte, which is redundant wrt to the array lenght.
Well, you didn't exactly elaborate on "strings". C provides both mutable
and immutable strings, and I imagine that Go provides the same, too
(although it would probably call the former byte arrays). There's no
issue with passing them to libs, since Go uses its own libs. The C code
it might interface with is a different (and irrelevant, given that the
same issue presents itself in any language-to-language interface) issue.
I took a look in Go's library, and it seems to me they are using
zero-terminated
strings. I bet they use the trick I talked about.
In Go, strings are indeed read-only byte arrays, but I'm not sure one may
pass
a byte array to a function that expects a string.
I don't agree that library interface is irrelevant to the language
implementation.
The availability of library bindings and their quality is 50% of a
language.
Hard to make bindings is a serious drawback IMO. I heard garbeam complained
about that on IRC, but OTOH his binding to xlib in godwm looks like a
trivial
thing.
Closures needn't be any more expensive than any other kind of function
reference,
[...]
I'll admit, though, that without the restriction that a closure is only
valid along with the current stack frame, closed over variables are
forced into heap allocation, but again it's no loss over other methods.
Yes, I was talking about closures :-)
You're right, it's certainly no more expensive than doing the
same in C, and perhaps even less expensive.
[...]
it's very easy to decide what is heap and what is static or stack
allocated in C, and I very much doubt that to be the case in Go (yes,
I'm citing memory management issues other than GC).
I don't understand your point. The removal of these storage specifications
is precisely one of the benefits of a GC; storage specifications only exist
because different objects in programs may have different lifespans, which
is
what the GC watches and manages.