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

Ruby compilation #1353

Closed
5 tasks
nex3 opened this issue Aug 2, 2014 · 3 comments
Closed
5 tasks

Ruby compilation #1353

nex3 opened this issue Aug 2, 2014 · 3 comments

Comments

@nex3
Copy link
Contributor

nex3 commented Aug 2, 2014

I've started playing around with compiling Sass to Ruby on this branch, so I'm creating this issue to track that work.

Compilation to Ruby is a performance feature. Currently (based on information from #1019) we seem to be losing a lot of time just to the overhead of running SassScript, and especially to thrashing the GC due to frequent object allocations. Compiling to Ruby allows us to offload a lot of the variable scope management and function call semantics to the underlying system, which will hopefully yield a substantial speed improvement.

Currently the aforementioned branch can successfully process very simple stylesheets. By adding straightforward Ruby-compilation logic for various additional AST nodes, we could pretty cheaply get a fair amount of functionality. However, there are still several major hurdles to overcome before it's ready to replace the current implementation:

  • Currently no source range information is preserved, thus rendering source maps useless. We need to compile this information in; the tricky part is doing so in a way that doesn't bloat the resulting code more than necessary.
  • There's currently no support for named arguments or variable-length argument lists. This is particularly awkward since Ruby doesn't natively support named arguments, and packing all argument lists into a hash seems likely to cause a lot of overhead. If we can determine which function or mixin is being called at compile-time, we'll likely be able to compile to a native Ruby function call at least in cases not involving var args.
  • We need to support the existing Ruby function API as much as possible. This becomes trickier when the notion of the "environment" is being handled by Ruby rather than Sass. Hopefully much of the information the current Environment API makes available can be lazily determined using Ruby's reflective capabilities, but some functionality may need to be removed for the sake of performance.
  • We need to preserve the existing errors and stack traces that Sass emits. We don't want to have to manually track the stack like we currently do in the Perform visitor, as this is likely to be a significant performance issue. Hopefully we'll be able to convert from Ruby errors and stack traces back into nice Sass traces. Demangling Sass names is easy enough, but tracking line numbers and files is more difficult. One solution might be to store a source-map-like data structure internally that allows us to determine the source line based on the Ruby line. It may also be possible to compile such that there's a one-to-one mapping from source lines to Ruby lines.
  • The Ruby compilation needs to be integrated into our caching strategy. We need to decide whether we want to cache only the compiled Ruby (which will save on space and serialization/deserialization time) or whether we want to continue caching the source tree as well (which is a better fit with our existing APIs).
@lolmaus
Copy link

lolmaus commented Aug 2, 2014

Ruby has recently got support for named arguments.

@nex3
Copy link
Contributor Author

nex3 commented Aug 2, 2014

Unfortunately, we can't target any language feature that's not available as far back as 1.8.7.

@nex3
Copy link
Contributor Author

nex3 commented Aug 21, 2015

My experiments with this never really panned out. I got a fair way into it, enough to start running performance tests, and the runtime perf gains just weren't worth the added complexity and the compile-time perf losses.

@nex3 nex3 closed this as completed Aug 21, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
2 participants