<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  <id>https://www.johnhawthorn.com/</id>
  <title>John Hawthorn</title>
  <updated>2025-10-19T00:00:00+00:00</updated>
  <link rel="self" href="https://www.johnhawthorn.com/atom.xml"/>
  <link rel="alternate" type="text/html" href="https://www.johnhawthorn.com/"/>
  <author>
    <name>John Hawthorn</name>
    <email>john@hawthorn.email</email>
  </author>
  <entry>
    <title>Searching Ruby's documentation</title>
    <id>https://www.johnhawthorn.com/2025/searching-ruby-docs/</id>
    <updated>2025-10-19T00:00:00+00:00</updated>
    <link rel="alternate" type="text/html" href="https://www.johnhawthorn.com/2025/searching-ruby-docs/"/>
    <content type="html">&lt;p&gt;The official Ruby docs are at &lt;a href="https://docs.ruby-lang.org/en/"&gt;https://docs.ruby-lang.org/en/&lt;/a&gt;. This
documentation (and any documentation built with rdoc 6.15.0 or greater) now can
be searched using a query parameter. Check it out!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.ruby-lang.org/en/master/?q=String%23gsub"&gt;https://docs.ruby-lang.org/en/master/?q=String%23gsub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.ruby-lang.org/en/master/?q=String%23gsub"&gt;&lt;img src="/static/images/ruby_docs_screenshot.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I &lt;a href="https://github.com/ruby/rdoc/pull/1396"&gt;added this to RDoc&lt;/a&gt; because I was
fed up with accidentally ending up on a horrible 3rd party website I won’t name
with 8+ year stale docs that Google inexplicably prioritizes.&lt;/p&gt;

&lt;p&gt;If you use &lt;a href="https://kagi.com/"&gt;Kagi Search&lt;/a&gt; you can now search &lt;code&gt;!rb
String#gsub&lt;/code&gt; and it will take you directly to the result.&lt;/p&gt;

&lt;p&gt;I appreciate that Kagi’s “bangs” are &lt;a href="https://github.com/kagisearch/bangs/pull/290"&gt;open source and accept contributions&lt;/a&gt;, but you don’t need to sign up for a service to have this ability. It seems a bit odd to me anyway to make an HTTP request just to be immediately redirected to another. Instead you can configure this right in your browser.&lt;/p&gt;

&lt;p&gt;In Firefox, go to Settings &amp;gt; Search &amp;gt; Search Shortcuts &amp;gt; Add. Use &lt;code&gt;https://docs.ruby-lang.org/en/master/?q=%s&lt;/code&gt; as the URL and whatever you want as the keyword (I like &lt;code&gt;!rb&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;In Chrome, essentially the same thing is at Settings &amp;gt; Search Engine &amp;gt; Manage search engines and site search &amp;gt; Site search &amp;gt; Add. The values work the same as for Firefox.&lt;/p&gt;

&lt;p&gt;&lt;img src="/static/images/ruby_docs_search.png" alt=""&gt;&lt;/p&gt;

&lt;p&gt;Stan Lo is also &lt;a href="https://github.com/ruby/rdoc/pull/1433"&gt;working on improving the quality of the results&lt;/a&gt;, so if you find the search underwhelming please check again once that’s shipped!&lt;/p&gt;

&lt;p&gt;Happy searching!&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Ruby might be faster than you think</title>
    <id>https://www.johnhawthorn.com/2024/ruby-might-be-faster-than-you-think/</id>
    <updated>2024-04-24T00:00:00+00:00</updated>
    <link rel="alternate" type="text/html" href="https://www.johnhawthorn.com/2024/ruby-might-be-faster-than-you-think/"/>
    <content type="html">&lt;p&gt;I saw a project a couple weeks back which allows &lt;a href="https://github.com/wouterken/crystalruby"&gt;writing and running Crystal
methods inline inside a Ruby file&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It’s a neat project, and I don’t want to take away from it but something in the
&lt;a href="https://github.com/wouterken/crystalruby/blob/1d8b38e103d5f3a210e0b6fbc5c1465cade62258/README.md"&gt;README example&lt;/a&gt; looked off to me.&lt;/p&gt;

&lt;pre class="language-ruby highlighter-rouge"&gt;
require 'crystalruby'
require 'benchmark'

module Fibonnaci
  crystalize [n: :int32] =&amp;gt; :int32
  def fib_cr(n)
    a = 0
    b = 1
    n.times { a, b = b, a + b }
    a
  end

  module_function

  def fib_rb(n)
    a = 0
    b = 1
    n.times { a, b = b, a + b }
    a
  end
end

puts(Benchmark.realtime { 1_000_000.times { Fibonnaci.fib_rb(30) } })
puts(Benchmark.realtime { 1_000_000.times { Fibonnaci.fib_cr(30) } })
&lt;/pre&gt;

&lt;p&gt;My benchmark runs look pretty similar to the README’s.
The “crystalized” version runs about 4x faster than the pure Ruby version.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ruby test.rb
2.113752398872748
0.6535678738728166
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But something is a bit off here. The Ruby implementation has a subtle mistake
which causes signficantly more work than it needs to.&lt;/p&gt;

&lt;p&gt;Ruby’s multiple assignment &lt;code&gt;a, b = b, a + b&lt;/code&gt; is equivalent to &lt;code&gt;a, b = [b, a + b]&lt;/code&gt;.
Most of the time that Array allocation doesn’t actually happen, but because in
this case it’s the last line of the block, and because Ruby has an
implicit return at the end of the block the Array is required (even though
&lt;code&gt;Integer#times&lt;/code&gt; doesn’t use the return we don’t yet have an optimization which
“knows” that).&lt;/p&gt;

&lt;p&gt;Let’s see how we do avoiding that… (with a slightly unsightly &lt;code&gt;; nil&lt;/code&gt; replacing the return)&lt;/p&gt;

&lt;pre class="language-ruby highlighter-rouge"&gt;
def fib_rb(n)
  a = 0
  b = 1
  n.times { a, b = b, a + b; nil }
  a
end
&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;$ ruby test.rb
1.245176327880472
0.6385665240231901
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Not bad. We’re making up the difference. Now we’re only about 2x slower than
crystal.&lt;/p&gt;

&lt;p&gt;To make this a bit faster, instead of calling &lt;code&gt;Integer#times&lt;/code&gt;, let’s inline the
loop.&lt;/p&gt;

&lt;pre class="language-ruby highlighter-rouge"&gt;
def fib_rb(n)
  a = 0
  b = 1
  while n &amp;gt; 0
    a, b = b, a + b
    n -= 1
  end
  a
end
&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;$ ruby test.rb
0.7689670620020479
0.638991191983223
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Nearly on par now! Finally, let’s enable YJIT, Ruby’s built-in JIT compiler to
see the real comparison.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ruby --yjit test.rb
0.10502525512129068
0.5002881051041186
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now it’s Ruby that’s 5 times faster than Crystal!!! And 20x faster than our
original version. Though most likely that’s some cost from the FFI, or
something similar, though that does seem like a surprising amount of overhead.&lt;/p&gt;

&lt;p&gt;I thought it was notable that by making some minor tweaks to Ruby code it can
now outperform a precompiled statically typed language in a purpose-built
example of when it is slow. I’m hopeful that someday with future advancements
in the Ruby JIT even the small tweaks might not be necessary.&lt;/p&gt;</content>
  </entry>
</feed>
