Live data from Hacker News

A little Golang way

aerofs.com

71–80 of 194 posts

Re: A little Golang way

#71
post #33

Earlier quoted context omitted.

> What you'll find is that your Go app will be extremely efficient and performant. This is true, for sure. But my experience--and I've written plenty of Go, though I find it unpleasant to write and think about for all the usual reasons that Go partisans roll their eyes and so would rather deal with it as artifacts rather than actually writing it--has led to watching lots of developers make mudball codebases in the pr…

> Go also discourages program extensibility through components Can you elaborate on this? Because in my experience with Go, I found that I had to make _far_ more components (assuming this means libraries?) than other languages. > Statically linking your SSL library makes you an asshole when it inevitably fails and now an application has to be regression-tested so that new features and new bugs don't hose you just bec…

With regards to your first question 'cause the sibling gets the second--I'm talking about a plugin architecture. Having to recompile an app to add a third-party feature is, in my world of "the user is more important than the developer," bogus; it means that I can't just use my OS packages if I need anything even remotely out of the ordinary. (nginx is the only thing I regularly use and might want to extend that has that misfeature, but it escapes that annoyance only because I've never needed to add a plugin Ubuntu doesn't by default.) Packer and Terraform attempt to get around this by shipping plugins as separate binaries. It is not the worst solution in the world, but I think it's an unpleasant, unsatisfying experience even when I do my best to separate that from just finding Go fugly in the first place.

It's an unrelated field to my day job of devops/server software, but I wrote a plugin system in .NET and it's super trivial to just suck down an assembly and expose its types to the core logic. I've written the same in Java, and Ruby basically makes it a breeze with a Gemfile and a 'require'. It can be slower (though for the overwhelming majority of tasks not at all too slow for a tool, rather than a high-throughput server or whatever) than Go can in some cases be, but it doesn't suck to use, and it's for that reason that while I can understand Go for server stuff I have a real beef with it intruding on my systems when I need to use it as a user.

Re: A little Golang way

#72

There have been several blog posts and conference presentations with a similar theme -- "Go is efficient, especially compared to X." I know it seems like hype, but I encourage others to try Golang out, maybe even slap a web app together with it. What you'll find is that your Go app will be extremely efficient and performant. It's kind of unfair to compare Go to many of the other languages of the web because it is com…

I wrote a small/medium size, non-trivial tcp-server in golang two years ago, in just about 2-3 weeks. It pretty much worked first try! So far 2 minor bugs.

Originally it was meant to be just a quick kick-golang-tires prototype, to be replaced with C++ later, but it turned out to work really well.

My impression of golang is that it's very useful getting things done. The code has also been readable to other people pretty much immediately, and they've been able to contribute features into it. None of us used golang previously.

Had I written same in C++, I bet there'd been a lot more bugs to fix.

Re: A little Golang way

#73

Earlier quoted context omitted.

> design patterns--and we should be reminded that design patterns exist to address defects in tooling This is a really important point, and I think it's why a number of best-practices in Go are actually not best practices in other languages, and vice versa. One of the explicit, top-level design goals of Go was to focus on creating top-notch tooling as part of the language. While it is not the only language that has t…

Top notch tooling? The debugger is neigh unusable. `go get` is a community joke. The compiler is fast mostly because it doesn't check for things that better compilers do. Go race is a symptom that not all is well in the CSP house. Other static analysis tools are third party and limited if they exist at all. Go really does remind me of JDK 1.4.

I'm sad that your post is downvoted, because (while I might have been a little more pleasant about it) I think you're generally on-point. The debugger is pretty poor, the compiler is pretty poor, there isn't much static analysis (and while the language's youth is an excuse, the profusion of tools for more semantically rich languages like Scala make me skeptical of the excuse).

I didn't mention Java 1.4 just for a lark; it's been long enough since I used it that I don't remember the ecosystem well but I do remember the style of coding being so brutally centered around type assertions and blind casts that Go really does remind me a lot of it.

Re: A little Golang way

#75
post #33

There have been several blog posts and conference presentations with a similar theme -- "Go is efficient, especially compared to X." I know it seems like hype, but I encourage others to try Golang out, maybe even slap a web app together with it. What you'll find is that your Go app will be extremely efficient and performant. It's kind of unfair to compare Go to many of the other languages of the web because it is com…

> What you'll find is that your Go app will be extremely efficient and performant. This is true, for sure. But my experience--and I've written plenty of Go, though I find it unpleasant to write and think about for all the usual reasons that Go partisans roll their eyes and so would rather deal with it as artifacts rather than actually writing it--has led to watching lots of developers make mudball codebases in the pr…

reinventing a lot of Java-1.4-era (because the language itself is essentially that) design patterns

Really? Java 1.4 had an extensive and consistent standard library, implicit interfaces, composition instead of inheritance, static builds, and built-in concurrency?

Go is not early Java, it's more like C 2.0, and I don't really see anything faux about the simplicity, it really is pretty simple, perhaps too simple for some tastes, but it's not pretending to be simple, nor is it simplistic. Which specific design patterns did you have in mind?

Re: A little Golang way

#76

Java's main feature is compile once - run (almost) anywhere. From embedded to mainframe as long as a JVM is available. How does Go stack up for cross-platform development? Does every application and library have to be (re)compiled for the target platform? What about support for alternative architectures (ARM, PowerPC, etc)?

Go does require recompilation for every platform, but I'll give them this, it's very painless. Apparently in 1.5 you can just set an environment variable for your architecture and one for your OS and you're good to go.

Re: A little Golang way

#77

And the cycle continues, from one crappy enterprise language to the next. I don't who said it, but whoever said "Go is a bold step backwards" is spot on.

There are times when a step back is the mandatory step to get a new perspective on things. Just sayin'.

Re: A little Golang way

#78
post #17

Earlier quoted context omitted.

> The relevance is that even a 175 LOC project in Java takes up enormous memory and disk footprint _This particular_ 175 LOC Java project takes up an enormous amount of memory. For all you know it was just coded poorly and the Go one is a bit more reasonable. > the JVM is this super-heavyweight thing that's really just inherently inappropriate for a lot of applications. The JVM introduces overhead but not so much tha…

The footprint of this particular service could have been optimized in Java but: 1. the JVM itself imposes a high floor (hotspot, many shared libs loaded, ...) 2. the Java language is full of overhead at every level (boxed types are a pet peeve of mine) 3. the Java ecosystem has a tendency to regard memory as an inexhaustible resource, which lead a lot of waste in many 3rd party libraries The core point is that optimi…

Point 2... yeah, that's one of my major problems with Java. Unnecessary boxing and the unreasonable amount of complexity if you work around it. In any type of Object collections, it consumes memory, stresses garbage collector unnecessarily and causes a lot of CPU cache misses.

Value types would help so much with this issue. I know they're coming one day. I hope Java/JVM can replicate memory efficiency and cache coherence of C++ std::vector for small objects.

Re: A little Golang way

#79
> Resident memory usage dropped from 87MB down to a mere 3MB, a 29x reduction!

This isn't so much Java vs. Go as it is JIT/interpreted vs. AOT-compiled. The numbers are entirely typical across a wide range of such comparisons.

With an interpreter or JIT, you need to load all your code at startup and process it. Generally, _all_ of your dependencies need to be loaded and parsed upfront, either converted to some internal in-memory representation or JIT'd directly to machine code. This will allocate a bunch of heap structures during the processing, and the end result is a bunch of data that needs to stay resident and can't easily be shared with other processes.

With AOT, you mmap() in a file. The OS only pages in the code you execute, and can page it back out as needed. Pages are shared between all processes running the same executable.

At sandstorm.io our rule of thumb is that an app written in Node, Ruby, Python, PHP, etc. will take 100MB of RAM while an app written in C++, Rust, or Go will take 2MB. Since Sandstorm runs per-user (and even per-document) app instances, this is a pretty big deal.

The good news is that https://github.com/google/snappy-start should fix this problem: by checkpointing the process after it finishes its parsing/JITing but before it starts handling requests, we can get an mmap-able starting state that is very much like an AOT-compiled binary. At least, in theory -- there's still a bunch of work to do for this to actually work in practice.

> The resulting docker image shrunk from 668MB to 4.3MB

While I would expect the Go image to be smaller (since Go builds static binaries, so literally all you need in the image is the binary), I suspect that the 668MB Java image was at least 90% unnecessary garbage that was not actually needed at runtime. Unfortunately the package managers we all use are not optimized for containers; instead they evolved targeting systems with dedicated disks that can easily absorb gigabytes of bloat.

In Debian, for example, every package implicitly depends on coreutils. That's perfectly reasonable when installing an OS on a machine: you almost certainly need a working shell to boot and administer your machine. But a container can get by just fine without coreutils, and a typical web server probably (hopefully) doesn't need to call out to a shell. Even if a shell is needed, busybox/toybox is probably sufficient and will take a lot less space.

Packages also often contain things like documentation, unit tests, etc. which obviously aren't needed in a container.

For Sandstorm.io we deal with this problem by running the app in a mode where we trace all the files it actually uses, and then we build a package containing only those. It mostly works and manages to keep packages reasonably-sized, but it does lead to bugs of the form: "I forgot to test this feature while tracing, so the assets it requires didn't make it into the package." We're looking for better options.

Re: A little Golang way

#80
post #67

Earlier quoted context omitted.

I think the parent was saying that new releases would bring new features the end user may not want, in addition to something like a security fix for an included library. With shared libs, you can keep using an old version if it works for you, while still updating ssl to a fixed version (assuming api compat).

This, precisely. If I have to compile YourApp 1.5 with YourTLSLib instead of just `apt-get upgrade`, I'm going to be sending you flaming karmic poop for your karmic doorstep. And not just new features--though SemVer is very often honored in the breach more than the observance--but breaking, sometimes undocumented changes (two Go projects, Packer and Terraform, both come to mind).

`apt-get upgrade` is not magic. Someone had to package the app for apt. Someone had to decide when to make a new release.

The same can be done for a Go app and it'll be available via apt just as any other app.

A fair comparison would be compiling a C/C++ app from sources vs. compiling Go app from sources and Go wins that contest easily.

Post reply on HN