Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Speed up rbenv by dynamically loading compiled command #528

Merged
merged 11 commits into from
Oct 15, 2014
Merged

Speed up rbenv by dynamically loading compiled command #528

merged 11 commits into from
Oct 15, 2014

Conversation

mislav
Copy link
Member

@mislav mislav commented Jan 6, 2014

The most time spent in rbenv execution is resolving paths to their absolute representations without symlinks. Manually doing this in bash is slow.

# rbenv overhead of running `ruby -e0`:
[system]
mean:    0.120
stdev:   0.008
[1.9.3-p194]
mean:    0.092
stdev:   0.003

By dynamically loading a compiled bash builtin, we can access the realpath POSIX C function which does exactly what we need and is fast.

# rbenv overhead with speed improvement:
[system]
mean:    0.086
stdev:   0.004
[1.9.3-p194]
mean:    0.057
stdev:   0.003

If dynamic loading fails, rbenv will still continue working as before (will fall back to shell implementation).

If RBENV_NATIVE_EXT environment variable is set, rbenv will abort if it didn't manage to load the builtin. This is primarily useful for testing.

Tested on OS X 10.9 and Ubuntu 12.

/cc @sstephenson

On systems that support both C compiling and dynamic loading, we can
speed up `realpath()` (where most time in rbenv is spent) by replacing
it with a dynamically loaded bash builtin.

When `make -C src` is called in the project's root,
`libexec/rbenv-realpath.dylib` will be created. If it exists, rbenv will
attempt to load it as a builtin command. If it fails, execution will
fall back to the old `realpath()` shell function.
With `realpath` extension, hooks tests on OS X will output
`/private/tmp` instead of `/tmp` because the latter is an actual symlink
to the former.

Avoid this mistmach in output assertions by expanding BATS_TMPDIR if
`realpath` extension is compiled.
This speeds up every `rbenv` invocation significantly.
It's slow and not necessary since we expect `$0` to already be expanded.

In tests this change forces us to deal with some relative paths, but
it's not a big deal. The `rbenv init -` output in the most common case
will be the same as before:

    source '/home/myuser/.rbenv/libexec/../completions/rbenv.bash'
Given the `-o <HOST-OS>` parameter, the script generates environment
variables with information how to compile dynamically loadable libraries
for that system.

Imported from bash-3.2.48
The `shobj-conf` script imported from bash seems to not support the
latest OS X. This makes sure that `SHOBJ_LDFLAG=-dynamiclib` is output
for Darwin10+ (latest version is Darwin 13.0).
The previous Makefile only worked on OS X. The dynamically generated
Makefile (from `Makefile.in`) should now work on multiple platforms
(tested on OS X and Ubuntu).
mislav added a commit that referenced this pull request Oct 15, 2014
Speed up rbenv by dynamically loading compiled command
@mislav mislav merged commit 39cde6f into master Oct 15, 2014
@mislav mislav deleted the dylib branch October 15, 2014 16:19
@thomasjo
Copy link

Nice!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants