The comparison between GO and Java seems unfair, given they compare a primitive variable with an object... which has methods and a bunch of other things to increase it's size (for good reason).
Sure GO may be quick... but a JIT'ed java program will run at native C speed... because it's been compiled down to native code at that point... (and most language performance comparison's I've seen pop up generally ignore this fact and measure "performance" by timing runtime which includes the JVM firing up and executing cold/non-jit'ed code... not real-world scenarios for high performance code.)
> The comparison between GO and Java seems unfair, given they compare a primitive variable with an object... which has methods and a bunch of other things to increase it's size (for good reason).
Honest question: will it be JIT'ed to the point where you no longer need 24 bytes to store an Integer in a List on a 64 bit JVM? Because if not, that comparison doesn't strike me as unfair, given that he explicitly mentions memory bound situations. Furthermore, will an array of Integers be a tightly packed set of integers, or value references to Integers? In general Go's equivalent to objects are structs, which seem to avoid this overhead of Java objects. Again, honest question; if Java can JIT all that away, awesome! :)
For the record, the people on the Go-nuts board are pretty adamant about microbenchmarks not being all that representative, and that people should give the JVM some time to do its optimisation (Robert Griesemer was one of the original programmers on the HotSpot compiler after all).
Well, the JDK's ArrayList, for example, will box ints into Integers, but there are primitive int lists that won't. With Go, AFAIK, the problem is exactly the same. Can you write, say, a heap or a read-black tree that can store wither ints and strings, that will embed the ints? Also, value types are making it into the JVM in Java 9. I don't think that will solve the packed representation in a generic data structure problem, but neither does Go. OTOH, Java does optimizations that Go never can. For example, Java can inline interface calls, which Go can't (and due to the way Go defines interfaces, method calls are slower than Java even when not inlined in either).
Having said that, there are things about Go that I like better than Java: 1) no implicit primitive promotions (widening conversions), 2) a small standalone executable, 3) excellent start up time. The latter two make Go suitable for quick, small programs, like command line tools etc.
However, there are more things I like about Java the Go doesn't have: 1) dynamic linking, 2) final variables, 3) concurrent data structures, 4) awesome monitoring and profiling tools, 5) generics, 6) state-of-the-art GC, 7) a polyglot VM (I also prefer Java's exceptions and explicit interface implementation, but these are minor considerations). So whenever I need serious, long-running, server-side software, I'd stick with Java over Go. Particularly now that Java has fibers (goroutines)[1] (I'm the main author).
> Can you write, say, a heap or a read-black tree that can store wither ints and strings, that will embed the ints?
I'm not sure I understand this sentence. Do you mean a union type? Or a generic datastructure? We all know Go doesn't have generics - that topic has been beaten to death, so let's not derail the discussion and just say this can be a valid reason for Go not fitting your use-case. But just for comparison, here's an implementation of a "generic" LLRB Tree in Go using interfaces and runtime reflection:
> We all know Go doesn't have generics - that topic has been beaten to death, so let's not derail the discussion and just say this can be a valid reason for Go not fitting your use-case.
Parents point was that Go will still box primitives in a generic collection class...just like Java does. So this isn't a special advantage of Go at all (it has nothing to do with Go not having type parameters). The only languages that don't box in generic collections is C++ and perhaps C# (it doesn't have to because of its template-like type parameter semantics, but still might to reduce code duplication).
Right. Although the template method has its own issues. For example, once the element type size exceeds 64 bits, you can no longer assume an atomic write/read. This isn't a big problem considering that concurrent data structures don't usually rely on the write/read atomicity of the elements themselves (though they do rely on atomicity of modifying internal, structural data), but that's just something to think about.
You couldn't write a generic tree that packs the ints closely together, no. But you could write a non-generic tree that does.
Also, Dave was talking about Lists, which you certainly can have packed with ints trivially in Go. And every piece of software I've worked on uses approximately a million times as many lists as trees. Obviously, this is application-specific, but I think it's pretty fair to say that most programs will use a lot more lists than trees. If your application uses a lot of trees, Go is probably the wrong language for you, unless you're willing to make a tradeoff by using code generation to generate type-specific implementations.
> But you could write a non-generic tree that does.
As you could in Java.
> Also, Dave was talking about Lists, which you certainly can have packed with ints trivially in Go.
What lists? Array lists? Linked lists? Skip lists? Concurrent array lists? Concurrent linked lists? Concurrent skip lists? Go gives you packed ints for only one kind of list.
> If your application uses a lot of trees, Go is probably the wrong language for you.
Or if it uses any advanced data structure that Go simply doesn't have, let alone concurrent data types (Java has such a rich collection of data structures, usually with state-of-the-art implementations). Or if you need dynamic code loading. Or embedding a scripting language.
I actually think Go is a very nice language, but Java is much more appropriate for serious, long-running, high-performance server-side apps.
That not, but most Java native code compilers (both JIT and AOT) do a relative good job of escape analysis and transform those new into stack allocations if possible.
Additionally, value types are already available as extensions in some JVMs like IBM's J9.
> The comparison between GO and Java seems unfair, given they compare a primitive variable with an object... which has methods and a bunch of other things to increase it's size (for good reason)
Nope, there's no "good reason" why java.lang.Integer is a full-blown Object with a heavyweight header and on-heap allocation. It doesn't need reference semantics, polymorphism, can't be inherited, it has a monitor but it's not terribly useful since the value is immutable, etc. The only reason why Integer is a java.lang.Object is that this is a constraint imposed by the typesystem so you can put the Integer in a collection or other kinds of code that manipulate "any object".
The comparison is completely fair; I don't think he's making the general statement that Go is faster than Java. He can legitimately make the claim that the overhead of a slice of ints is far smaller than an array of ints in Java.
You can add methods to an int in Go without any overhead by simply defining your own type that is backed by an int and then adding functions to that type. It still costs same.
Java performance for real-world, long-running, well written applications is greatly enhanced by an excellent JIT that improved performance over time. Go can be faster for looping over a list of integers while Java can win at branch prediction in complex code paths.
> He can legitimately make the claim that the overhead of a slice of ints is far smaller than an array of ints in Java.
No he can't. He was comparing a generic list in java of ints with a non-generic list of ints in Go, when in reality, you could reverse the comparison between languages and make the same conclusion.
You don't need <generic-equivalent-boxing> in Go to get the power of slices, and use library search/sort. Are you saying there's an equivalently powerful set of facilities in Java that doesn't use generics?
Yes, they are called...slices. There is no library implementation in Java, but it is completely implementable (I did the whole thing for Scala way back). Say:
class Slice {
int[] Original;
int Begin;
int End;
int Get(int index) {
if (index > End - Begin) throw new ...
return Original[Begin + index];
}
}
Perhaps Go slices are native and they can eliminate one extra bounds check? Or that you don't have to implement a custom slice class for N primitive/value types (though Java doesn't support value types yet)? Since the code is easily templated, you could just use SugarJ or some other macro system for Java.
It is ugly without generics though, and...beyond defining slices, Go has most of the same usability problems as Java (all operations on slices have to be duplicated!). C#-style generics fix these problem, of course...meaning you can have your slice of cake and eat it also.
Yes, they are called...slices. There is no library implementation in Java, but it is completely implementable...
Perhaps Go slices are native and they can eliminate one extra bounds check? Or that you don't have to implement a custom slice class for N primitive/value types (though Java doesn't support value types yet)? Since the code is easily templated, you could just use SugarJ or some other macro system for Java. Or that you don't have to implement a custom slice class for N primitive/value types (though Java doesn't support value types yet)? Since the code is easily templated, you could just use SugarJ or some other macro system for Java.
You definitely lost the conversation context, or this is some kind of debating maneuver? The point is that the memory overhead for the degree of functionality offered by slices in Go is quite small by design. Yes, you can implement it in Java, but various kinds of overhead (not just memory, btw) in Go are small by design. Then comparative implementation details are discussed to provide context for programmers who may not concentrate on language implementation.
You're also kind of barking up the wrong tree. Go is not really meant to replace Java. It's really meant to "replace" C, or more accurately bridge a gap a bit higher-level than C and lower level than "High Level Languages," particularly where concurrency is of key importance. In the contexts where it seems to try and replace Java or C++, it's really that a locus of language implementation tradeoffs wasn't immediately identified and languages with slightly too many features were used to fill the gap.
C#-style generics fix these problem, of course...meaning you can have your slice of cake and eat it also.
No one is arguing that C# style generics don't fix this, or that certain things are less pretty without them, or that other languages can or don't do certain things more elegantly. In particular, yes, I know C# is very underrated. Camp Smalltalk attendees knew about the cool things about the Common Language Runtime about a year and a half before the public. (One camper declared that it basically meant "Smalltalk had won.") We hear you and believe you and you are right. Validated? Now please stop repeating yourself. That's simply not the key "point" which was made by the post and is not being understood in these threads. That point is not being made nor even being addressed by you.
Take it from an old Smalltalker: doing cool stuff yields 100X more benefit than comparing languages and tooting your own horn. Goes even more for objecting to others tooting theirs.
EDIT: When I say "no one would say that," I really mean, "no one reasonable would say that." As you and I well know, this precludes many programmers while they are in a holy language-war discussion.
What is Java's startup and JIT overhead? Go seems to be a good replacement for when you need a faster Python. For large, long running programs the JIT probably has better optimizations than the current Go compiler.
That's pretty much because the CPU on the Pi is awful. I mean really bad. The CPU came with the SoC they could get their hands on rather than was selected as being optimal for a desktop/server role.
Beating java in memory usage is like beating a tied-up blindfolded turtle you gave cement shoes and dropped into a toxic vat in the 100 meters walking.
You know, if the turtle was disqualified ahead of time.
Now let's compare how many lines it takes to read in 2 csvs into structs, sort them by their normals and write their vector products out into a new file. I bet java will do < 100 lines and go will be 10 files and > 1000 lines. It'd be about as honest.
Sure GO may be quick... but a JIT'ed java program will run at native C speed... because it's been compiled down to native code at that point... (and most language performance comparison's I've seen pop up generally ignore this fact and measure "performance" by timing runtime which includes the JVM firing up and executing cold/non-jit'ed code... not real-world scenarios for high performance code.)