Skip to content

Instantly share code, notes, and snippets.

@shirosaki
Created May 16, 2012 16:58
Show Gist options
  • Save shirosaki/2712204 to your computer and use it in GitHub Desktop.
Save shirosaki/2712204 to your computer and use it in GitHub Desktop.
faster-windows-ruby-requires.md
diff --git a/_site_src/content/posts/2012-05-15-faster-windows-ruby-requires.md b/_site_src/content/posts/2012-05-15-faster-windows-ruby-requires.md
index 6f0ada8..160f518 100644
--- a/_site_src/content/posts/2012-05-15-faster-windows-ruby-requires.md
+++ b/_site_src/content/posts/2012-05-15-faster-windows-ruby-requires.md
@@ -49,6 +49,67 @@ int main(int argc, char *argv[])
<% end %>
</code></pre>
+## Why the current Ruby 1.9.3 is so slow on startup?
+
+This is because of the usage of `FindFirstFile()` API in `File.expand_path`.
+
+`require` calls a lot of `expand_path` against `$LOAD_PATH`. `expand_path` performance seems a big bottleneck of startup time. `FindFirstFile()` looks quite slow because of File system operation. This is used for short path name expansion to long path name of the base name. Ruby on Linux doesn't need such expensive operation.
+
+We found skipping `FindFirstFile()` call gives big performance improvement.
+
+<pre><code class='language-diff'>
+<% h do %>
+diff --git a/file.c b/file.c
+index 11e9766..39aacc2 100644
+--- a/file.c
++++ b/file.c
+@@ -3196,7 +3196,8 @@ file_expand_path(VALUE fname, VALUE dname, int abs_mode, VALUE result)
+ wstr = ALLOCV_N(WCHAR, v, len);
+ MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(tmp), -1, wstr, len);
+ if (tmp != result) rb_str_resize(tmp, 0);
+- h = FindFirstFileW(wstr, &wfd);
++// h = FindFirstFileW(wstr, &wfd);
++ h = INVALID_HANDLE_VALUE;
+ ALLOCV_END(v);
+ if (h != INVALID_HANDLE_VALUE) {
+ size_t wlen;
+/* vim: set sw=4 sts=4 et */
+<% end %>
+</code></pre>
+
+
+
+### Rails 3.2.1 empty app startup
+
+#### Plain ruby 2.0.0dev (2012-02-18 trunk 34670) [i386-mingw32]
+<pre><code class="language-shell">
+<% h do %>
+X:\empty>timer ruby script\rails r 'p $:.size, $".size'
+59
+744
+real 6.708
+system 4.227
+user 2.433
+<% end %>
+</code></pre>
+
+
+#### Patched ruby 2.0.0dev (2012-02-18 trunk 34670) [i386-mingw32]
+<pre><code class="language-shell">
+<% h do %>
+X:\empty>timer ruby script\rails r 'p $:.size, $".size'
+59
+744
+real 2.418
+system 0.920
+user 1.513
+<% end %>
+</code></pre>
+
+It reduces 6.7s to 2.4s!
+
+Instead of performance gain, short path is left as it is. Windows users can do short path name expansion by `GetLongPathName` API using `dl` library if it's needed.
+
## Building a Quicker Ruby 1.9.3
_in progress_
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment