Skip to content
HomeVideosBooksBlogs
AllTop postsTopics
Podcasts
HistoryListsWatch laterLiked videosFollowing

The videos, books, blogs and podcasts Hacker News keeps recommending, all in one place.

VideosBooksBlogsPodcastsAboutPrivacySettings

Data from Hacker News, HackerTube, HackerBooks, HackerBlogs and Open Library. Credits · Not affiliated with Y Combinator.

HomeVideosBooksBlogsPodcasts
Ctrl K

    Steve Hanov

    stevehanov.ca · Personal blog · on HN since 2009

    Steve Hanov, a programmer and founder, writes about algorithms, data structures, A/B testing, and running small software businesses.

    Visit blogRSSHN submissions
    ProgrammingStartups
    What HN says

    Commenters call his articles classics, especially on bandit algorithms and tries, and say they have followed his C++-heavy blog for years.

    Stats for nerds
    106HN people shared it
    72linked in comments
    3.8Kstory points
    Apr 2026last shared
    2009people per year2026

    Top posts on HN

    1. 1
      20 lines of code that beat A/B testing every time
      11 people · 1.9K points · first shared 2012 · 176 comments on HN
    2. 2
      The multi-armed bandit problem (2012)
      2 people · 304 points · first shared 2019 · 79 comments on HN
    3. 3
      Fast and easy Levenshtein distance using a trie (2011)
      4 people · 168 points · first shared 2011 · 38 comments on HN
    4. 4
      “Your program is stupid. It doesn't work,” my wife told me (2010)
      3 people · 164 points · first shared 2010 · 54 comments on HN
    5. 5
      Succinct Data Structures: Cramming 80,000 words into a Javascript file
      6 people · 127 points · first shared 2011 · 10 comments on HN
    6. 6
      VP trees: A data structure for finding stuff fast
      3 people · 113 points · first shared 2011 · 9 comments on HN
    7. 7
      How to detect if an object has been garbage collected in JavaScript
      1 person · 113 points · first shared 2020 · 72 comments on HN
    8. 8
      Fast Levenshtein distance using a Trie
      4 people · 107 points · first shared 2011 · 16 comments on HN
    9. 9
      C++: A language for next generation web apps
      4 people · 104 points · first shared 2010 · 95 comments on HN
    10. 10
      Minimal Perfect Hashing
      5 people · 86 points · first shared 2011 · 10 comments on HN

    What HN people wrote when they linked it

    • btillyMay 2012

      Most or all of the points suffer from:

      Let's address them one by one.

      is that actually true?

      In every case, yes.

      does regular a/b testing not also face that issue?

      For the big ones, regular A/B testing does not face that issue. For the more complicated ones, A/B testing does face that issue and I know how to work around it. With a bandit approach I'm not sure I'd have noticed the issue.

      was it suggested that you must "set it and forget it"?

      Not "must", but it was highly recommended. See paragraph 4 of http://stevehanov.ca/blog/index.php?id=132 - look for the words in bold.

      are there no mechanisms for mitigating these issues?

      There are mechanisms for mitigating some of these issues. The blog does not address those. As soon as you go into them, you get more complicated. It stops being the "20 lines that always beats A/B testing" that the blog promised.

      I was doing some back of the envelopes on different methods of mitigating these problems. What I found was that in the best case you turn into

      would using 20% or 30% mitigate the issues?

      That would lessen the issue that I gave, at the cost of permanently worse performance.

      The permanent performance bit can benefit from an example. Suppose that there is a real 5% improvement. The blog's suggested approach would permanently assign 5% of traffic to the worse version, for 0.25% less improvement than you found.

      Now suppose you tried a dozen things. 1/3 of them were 5% better, 1/3 were 5% worse, and 1/3 did not…

    • LoicMar 2015

      Effectively, you need to keep a small heap and if possible have "simple" data structure. In my case, I implemented the Python code of a trie based levenshtein distance algorithm[0]. I used maps because it was basically a direct translation of the Python code. This resulted in millions of maps and oft the index would just stop in the garbage collector for a couple of seconds. I solved it using my own map which is travelled linearly.

      type SpellCheckerMap struct {
      Runes []rune
      Nodes []*SpellCheckerNode
      }

      with only few runes, I can just go through the list to find the index of the following node. You save the computation of the map hash key. It is pretty fast, here is an example of a spelling suggestion over a 500,000 words corpus[1].

      Basically, the garbage collection cost forced me to think about a better data structure for my case. Maybe not that bad all in all.

      [0]: http://stevehanov.ca/blog/index.php?id=114
      [1]: https://www.chemeo.com/search?q=asparine

    • stonemetalAug 2012

      One of the draw backs that typically gets mentioned about current distributed systems is the lack of locking which makes managing un-merge-able (binary) files impossible to manage correctly. This is why you will not hear of many game dev studios using git, version controlling art assets is fairly common in such situations and perforce handles it like a champ. DVCSs in general tend to have performance issues with large files, I know mercurial warns you about the performance implications of storing anything over 10MB.

      A bit old(2009) so it may have changed, but here is a rant about the scalability of git vs perforce.
      http://stevehanov.ca/blog/index.php?id=50
      and a little newer post on git scalability issues:
      http://news.ycombinator.com/item?id=3548824

    • jones1618Oct 2012

      Just because a problem has been "solved" for one platform (Fast PC's w/ Gigabytes of ram/disk) doesn't mean it is solved for all platforms (Web apps for phones/tablets, etc).

      John Resig (of jQuery and Khan Academy fame) had a really interesting thread on creating a fast-loading (i.e. small, efficient) dictionary for a JavaScript app. http://ejohn.org/blog/revised-javascript-dictionary-search/

      The comments have some really clever ideas for encoding the dictionary and Resig weighs in on his favorite solution with informative data. There's an interesting "Succinct Trie" data structure that turns a 620K dictionary into a 220K string that doesn't need to be decoded to be searched.
      http://stevehanov.ca/blog/index.php?id=120

    • karterkJul 2019

      The trie is my favorite data structure. It allows you to build inverted indices (i.e. hashmaps) that can also be used for prefix lookups of tokens and for spelling/typo correction.

      With a trie, it's very efficient to calculate Levenshtein distances. Here's a post (http://stevehanov.ca/blog/?id=114) that has a good primer on that.

      If you love this sort of thing, here's a fast and neat memory efficient Trie variant: https://db.in.tum.de/~leis/papers/ART.pdf (Adaptive Radix Tree).

      I've used ART as a building block to create an open source typo tolerant search engine called Typesense (https://github.com/typesense/typesense).

    • nlFeb 2020

      I think practical solution to this is to return all words that are within a Levenshtein distance[1] of 2*number_accented_characters of the original word, ranked by the distance.

      Levenshtein distance can be calculated using a trie[2] so it's fast enough for most purposes.

      If you wanted to get fancy you could modify the Levenshtein to reduce the distance penalty on accented characters, and/or only apply the Levenshtein calculation within 1 character of an accented character or the equivalent ASCII substitution sequence.

      [1] https://en.wikipedia.org/wiki/Levenshtein_distance

      [2] http://stevehanov.ca/blog/?id=114

    Related

    Aphyraphyr.com551 people

    Hexing the technical interview (2017)

    Aphyr
    Personal · last shared 2026
    John Regehrblog.regehr.org401 people

    Teaching C

    John Regehr
    Personal · last shared 2026
    Steve Yeggesteve-yegge.blogspot.com839 people

    Kotlin Is Better

    Steve Yegge
    Personal · last shared 2026
    Gunnar Morlingmorling.dev56 people

    The One Billion Row Challenge

    Gunnar Morling
    Personal · last shared 2026
    Erik Bernhardssonerikbern.com150 people

    Why software projects take longer than you think – a statistical model

    Erik Bernhardsson
    Personal · last shared 2026
    Steve Klabnikwords.steveklabnik.com284 people

    A Sad Day for Rust

    Steve Klabnik
    Personal · last shared 2026
    Mat Ryermedium.com/@matryer23 people

    Vice: Go channels across many machines

    Mat Ryer
    Personal · last shared 2025
    A Smart Bearblog.asmartbear.com407 people

    Avoid blundering: 80% of a winning strategy

    A Smart Bear
    Personal · last shared 2026