Jason Moiron
jmoiron.net · Personal blog · on HN since 2009
Jason Moiron, a Go developer, writes about Go, Python performance, databases, and programming language opinions.
What HN saysHN commenters cite his posts on why CPython is slow and on Go's database/sql, and one likes his minimal blog design.
36HN people shared it
10linked it in comments
29stories submitted
1.6Kstory points
9 months agolast shared
2009people per year2026
Most-shared posts
- 1What's Going On (on "Why Python, Ruby, and Javascript are Slow")4 people · 295 points · first shared 2013 · 192 comments on HN
- 2Is K8s Too Complicated? 3 people · 274 points · first shared 2018 · 166 comments on HN
- 3C++ Deserves Its Bad Reputation3 people · 4 points · first shared 2020 · discussion on HN
- 4Golang ORMs3 people · 2 points · first shared 2013 · discussion on HN
- 5About SQLAlchemy and Django's ORM3 people · 2 points · first shared 2009 · discussion on HN
- 6For Better or for Worse2 people · 63 points · first shared 2015 · 33 comments on HN
- 7Mmap(2)2 people · 61 points · first shared 2015 · 22 comments on HN
- 8Wirth's Revenge2 people · 3 points · first shared 2026 · discussion on HN
- 9Python Serialization Methods comparison2 people · 2 points · first shared 2012 · discussion on HN
- 10Go Performance Tales1 people · 296 points · first shared 2014 · 41 comments on HN
- 11Thoughts on Time-series Databases1 people · 226 points · first shared 2015 · 127 comments on HN
- 12Notes on the Go2 Generics Draft1 people · 148 points · first shared 2018 · 114 comments on HN
- 13Github has won1 people · 95 points · first shared 2010 · 52 comments on HN
- 14Japanese peer-to-peer (2008)1 people · 88 points · first shared 2013 · 32 comments on HN
- 15Cote D'Azur – Performance of pi calculation in multiple languages (2013)1 people · 15 points · first shared 2014 · 9 comments on HN
What HN people wrote when they linked it
jmoiron · 2013-05-23
I've independently come up with the same decisions on many of these points and, weirdly, a very similar blog design:
http://jmoiron.net
I decided even to dispatch with the header bar, putting navigation at the bottom of the main page; presumably, people will only care to see more of my writing if they've read the article. Not as good for people revisiting the page, but they can likely remember http://jmoiron.net/blog or bookmark it in order to get to the search.
My fonts are slightly smaller and slightly less contrast, and after looking at Gemmell's blog I wonder if I should change that decision. I wanted to have emphasized elements of the text easily distinguishable from the body while not distracting.
Also, I agree with Gemmell's "The basic tenets of hypertext should be left alone". One of these basic tenets, to me, are the semantic meanings of Blue, Purple, and Red text for normal, :visited, and :active hyperlinks. If you want to chose a link color, do not invert or violate these classical meanings.
shanemhansen · 2014-11-18
cPython does alot of work for just about any piece of code. Just a small handful of things:
1. everything's a hash (object data, variable lookup, etc). jmoiron wrote a great article on the topic http://jmoiron.net/blog/whats-going-on/
2. refcounting introduces overhead for every variable access
3. loops are making all kinds of function calls to __iter__, next(), and catching StopIteration, which makes it hard to have a tight loop.
4. There's the GIL, builtin locking isn't great.
5. lots of indirection (lack of value types)
buro9 · 2014-06-23
There are a couple of good resources you can use here, the first is just about the best reference for using Go with a RDBMS:
http://go-database-sql.org/
The second speaks of database connections:
http://jmoiron.net/blog/gos-database-sql/
The general approach:
1. Use a single DB connection, it will pool automatically
2. Use this pattern for all single row queries:
err = db.QueryRow(`...`, ...).Scan(&...)
if err == sql.ErrNoRows {
// Handle no rows
} else if err != nil {
// Handle actual error
}
// All fine
3. Use this pattern for all multi-row queries where you want to return a slice of structs containing the row values. Note that it is fine to call rows.Close() as soon as possible in addition to deferring it, defer takes care of handling it whenever something goes wrong and the explicit call returns the connection as soon as possible:
rows, err := db.Query(`...`, ...)
if err != nil {
// Handle connection or statement error
}
defer rows.Close()
things := []rowStruct{}
for rows.Next() {
thing := rowStruct{}
err = rows.Scan(
&thing.id,
&thing.value,
)
if err != nil {
// Handle row parsing error
}
things = append(things, thing)
}
err = rows.Err()
if err != nil {
// Handle any errors within rows
}
rows.Close()
4. Use transactions as serial things, if you need to call another query whilst in a loop where you can't rows.Close(),…
chimeracoder · 2014-01-26
I'm going to chime in, since I've been using Go as my primary language for over a year, and I'm currently working on a major (production) Go project that others might see as well-suited for Rails (in fact, the early prototype was written in Rails[0])
> The thing no framework I have seen so far addresses is persistence. SQL persistence in Golang is a bit of a nightmare. It's raw SQL, and the database libraries are fussy.
> The thing that makes Rails so easy to write in, especially for newcomers, is ActiveRecord. As far as I can tell, nothing like it exists (in a stable form) for Golang.
I wouldn't recommend newcomers to Go use SQL right off the bat. Document-based storage (like CouchDB or MongoDB), or even key/value (Redis, etc.) is much more aligned with Go's concept of structs, and all three of those databases have strong library support in Go. If you're just looking to dabble in Go and just happen to need a database (and it doesn't matter which), I'd recommend playing around with those first. Even Neo4j works very well with Go, though as of January 2013 (when I last used it), the only Go library for Neo4j was third-party, and not very well-documented.
That said, once you know the Go language, using SQL (either with or without an ORM) is straightforward, if not as convenient as ActiveRecord. jmoiron has a good blog post[1] comparing the good, bad, and ugly of Go ORMs, so I won't try to top that here - rather, I'll share my experience.
(As pointed out elsewhere, ORMs…
MrJohz · 2025-08-18
For Go, they have a statistic from a few years back that suggests about 98% of a cross section of real-world Go projects are formatted according to gofmt. (https://jmoiron.net/blog/fmty-dmpty) I can believe Rustfmt and other tools not having quite the same reach, but I would guess that the proportion is still pretty high.
These tools are very standard and very widely used.
> Don't you want to see neatly formatted code while you're writing it?
Every time I pause, I press ctrl-S or an equivalent. So I really am seeing neatly formatted code while I'm writing it. I would guess that 90% of the time, if my code is syntactically valid, it's also neatly formatted. And even if it's not valid code, it's probably very close to being neatly formatted.
steveklabnik · 2020-10-18
The first person to write a response post to the original post used Go, with an even more aggressive title than this (IMHO) http://jmoiron.net/blog/cpp-deserves-its-bad-reputation/
A bunch of people have been doing it in a bunch of languages. It’s kind of the natural way to explore the topic.
kyrra · 2014-04-22
There are a number of ORM implementations in Go: http://jmoiron.net/blog/golang-orms/
As you said, Go doesn't lend itself to this like some other languages, but it can work.
bwooceli · 2010-11-10
Wow, actually had an article starred on this in the trusty Reader. http://jmoiron.net/blog/about-sqlalchemy-and-djangos-orm/
Money quote for me: "SQLAlchemy is a toolkit for python programmers who want or need to use a database to write programs that do so. Django's ORM is a tool for python programmers to quickly model business-level data relationships and use a database for persistent storage. This is really an important distinction; the Django ORM interface is focused on the application's data model, whereas SQLAlchemy's interface is focused on the underlying data store."
wmblaettler · 2010-03-02
Also some discussion here by the project co-author: http://jmoiron.net/blog/johnny-cache/
pansa2 · 2020-10-29
> I often describe Go as the strongly-typed, more performant version of Python.
I've heard Go described this way several times, but I've found it to be a significantly lower-level language than Python.
For example, it's much more verbose. In this recent blog post [0], the author converts some C++ code to Go - and it gets longer. 57 lines of C++ become 65 lines of Go. The same code in Python is about 20 lines.
In particular, the author's Go code requires five lines to do the equivalent of Python's `with open(path) as f` and four lines for the equivalent of `word_array = list(word_counts.items())`:
f, err := os.Open(path)
if err != nil {
return err
}
defer f.Close()
// [...]
wordArray := make([]WordCount, 0, len(wordCounts))
for word, count := range wordCounts {
wordArray = append(wordArray, WordCount{word: word, count: count})
}
[0] http://jmoiron.net/blog/cpp-deserves-its-bad-reputation/