Live data from Hacker News

How to Fix Slow Code in Ruby

engineering.shopify.com

171–180 of 213 posts

Re: How to Fix Slow Code in Ruby

#171

Earlier quoted context omitted.

If you want the luxury of scale problems down the road you do RoR until you lock down that first couple billion dollars of valuation. Just ask Stripe, Github, AirBnB, Gusto, Shopify, Coinbase, Dropbox, Twitter, Door Dash etc. Then you can have the "problem" of picking the wrong language. Massive survivorship bias in the panning of Ruby/RoR IMO... Also the Ruby/RoR community and culture is better than most other langu…

Edit: downvote away for disagreeing. I don’t see anyone presenting a counter argument. This has not been my experience. It has been “do it THIS way in ruby” even though either way is perfectly valid (eg list of Literal strings / symbols vs %i or %w. Lots of bike shedding type discussions on which way is better and unsurprisingly no consistency across the codebase. There’s also a lot of hidden things you can only lear…

I find that Rails apps tend to have some of the most consistent styling (within the codebase, and between codebases) of any language/framework out there. There's generally the "Rails" way of doing things, usually whatever Rubocop defaults to.

Also, "perfectly valid" doesn't mean "good", or "best practice", most style rules tend to reason beyond just looking pretty. String literals are slower and use more memory than symbols, and they're harder to grep for (either visually or with grep) in the codebase. More importantly, it's a lot clearer in code what a symbol's intent is, it's an immutable internal identifier, whereas strings should be used for storing data. Strings are mutable, which can be a source of bugs, a fairly trivial example would a developer making a typo and writing `str += 'label'` instead of `str = 'label', using symbols would raise an exception. Same for using %i or %w for arrays of integer or words, it ensures that the contents of the array are of a consistent type (at least at that point). Personally I don't think it should be a strict rule (I've turned the lint rule off on our codebase), but I do use them where appropriate, in particular when defining a constant as an array as it makes it clear to others reading the code what its intent is.

The only real complaint I have about Ruby style is that there's a million ways to work with enumerables, often with subtle differences in behaviour. For example, extracting a value or default from a hash is commonly done with `hash[:val] || 'default'` or `hash.fetch(:val, 'default')`, if the the key exists in the hash, but with a falsey value (nil or false), it will return 'default', but the second will return the falsey value. This can be good or bad depending on your specific use case, but I've come across unexpected behaviour from both versions.

I definitely agree with you about hidden features though. I've spent hours this week reading through different gems' source code because the documentation was lacking, at least it's generally readable code. It's frustratingly common when reading gem docs for me to find `#method(opts={})` as the method signature, with no additional explanation as to what parameters it takes.

I much prefer Ruby having a prescriptive style guide that the majority of developers use, I can look at the source code for any gem or app and immediately be familiar with how it looks, it's a lot less overhead when starting on new codebases. Compare this to C, where there's half a dozen different conventions on where to put your curly braces, or JS, where there's arguments as to whether lines should end with a semicolon.

You're right that a lot of ruby developers are pretentious, especially compared to Java or C# developers. Most Ruby developers are programming/technology enthusiasts, they have a passion and interest in what they do, I spend a fair amount of my spare time programming, or reading about programming. This is especially true for experienced developers (before bootcamps were all teaching Rails), they learned Ruby in their own time, not at university.

On the other hand, a lot of Java/C#/Python devs do it as a job and nothing else, which there's absolutely nothing wrong with, everyone has different hobbies and interests. One of my coworkers was previously a Java developer, and he has no particular interest at all in programming, he would probably be just as happy as an accountant, he spends his spare time painting or with his family.

Re: How to Fix Slow Code in Ruby

#172

Earlier quoted context omitted.

What makes you say that? method_missing is trivial with a tracing JIT and Chris Seaton's PhD covers how to do it for a method JIT.

Which tracing jit would you recommend for production work? The implication is, of course, that there isn’t a good one. This isn’t ruby the language’s fault, it’s just weird that after like 15 years being the go-to tool for VCs there’s no substantial investment in the core infrastructure. We just gotta wait for banking software to be written in it, I guess, so there’s a vested interest in it over the long term. Edit:…

JRuby optimizes method_missing in production right now so there's no need to wait for a tracing JIT.

I hope that Shopify will start to invest more into R&D for CRuby as well now as well as having Chris there working on TruffleRuby.

I'm not sure what you're trying to say with the last part because Ruby works quite differently to Lua or Self here and Self has been "fast" for 30+ years anyway.

Re: How to Fix Slow Code in Ruby

#173

Earlier quoted context omitted.

Which tracing jit would you recommend for production work? The implication is, of course, that there isn’t a good one. This isn’t ruby the language’s fault, it’s just weird that after like 15 years being the go-to tool for VCs there’s no substantial investment in the core infrastructure. We just gotta wait for banking software to be written in it, I guess, so there’s a vested interest in it over the long term. Edit:…

JRuby optimizes method_missing in production right now so there's no need to wait for a tracing JIT. I hope that Shopify will start to invest more into R&D for CRuby as well now as well as having Chris there working on TruffleRuby. I'm not sure what you're trying to say with the last part because Ruby works quite differently to Lua or Self here and Self has been "fast" for 30+ years anyway.

> JRuby optimizes method_missing in production right now so there's no need to wait for a tracing JIT.

Surely this would reflect in benchmarks? Perhaps there is an even slower aspect of the language manifesting in JRuby....

> I'm not sure what you're trying to say with the last part because Ruby works quite differently to Lua or Self here and Self has been "fast" for 30+ years anyway.

Is this supposed to reflect in Ruby’s favor? Self was built to be performative in spite of its novel features—the slow aspects of the language were never encouraged to take a central role. A better equivalent might be applescript or bash or a language that emphasizes some particular quality of expressiveness.

Re: How to Fix Slow Code in Ruby

#174

I wonder what would be more efficient, constantly trying to eke out some performance out of a inherently slow language? Or writing/rewriting new/critical paths of the codebase in a faster language. Ruby used to be able to say we sacrifice performance for developer productivity. I don’t think this is any longer true, there’s plenty of languages out there that developers can be just as productive with, while producing…

> there’s plenty of languages out there that developers can be just as productive with There aren't that plenty really. Golang has nothing like Rails, neither does Node. You can say Django / Laravel but then it's the same performance issues. Or maybe you're talking good old enterprise software like Spring / Asp. I don't think Ruby/Rails should feel inferior to any of those names for web development.

I think you can absolutely be just as productive with JS, but it's also easy to be incredibly unproductive.

The problem I have with JS (both for server side and client side) is that there's usually several different packages/libraries/frameworks to achieve the same goal, and often one gets deprecated in favour of another, requiring constant updates and changes to the development and build environment. JS development is all about the flavour of the week. For example gulp/grunt/webpack, or NPM/bower/yarn. This is compounded by the lack of a standard library.

Every company has its own particular build system (and configuration of that system), libraries they use, style guide, and file/folder layout. It's also very easy to abuse scoping and class mutability, with only style guides and eslint to save you. It can be a lot of work keeping a larger and older project up to date.

Re: How to Fix Slow Code in Ruby

#175

Earlier quoted context omitted.

JRuby optimizes method_missing in production right now so there's no need to wait for a tracing JIT. I hope that Shopify will start to invest more into R&D for CRuby as well now as well as having Chris there working on TruffleRuby. I'm not sure what you're trying to say with the last part because Ruby works quite differently to Lua or Self here and Self has been "fast" for 30+ years anyway.

> JRuby optimizes method_missing in production right now so there's no need to wait for a tracing JIT. Surely this would reflect in benchmarks? Perhaps there is an even slower aspect of the language manifesting in JRuby.... > I'm not sure what you're trying to say with the last part because Ruby works quite differently to Lua or Self here and Self has been "fast" for 30+ years anyway. Is this supposed to reflect in R…

It does? JRuby 9.2 can be 15% (web), 25% (optcarrot), maybe 3x faster (microbenchmarking iterators) than CRuby depending on what you're doing.

Did you mean messages? They're certainly a central part of Self.

Re: How to Fix Slow Code in Ruby

#176

Earlier quoted context omitted.

> JRuby optimizes method_missing in production right now so there's no need to wait for a tracing JIT. Surely this would reflect in benchmarks? Perhaps there is an even slower aspect of the language manifesting in JRuby.... > I'm not sure what you're trying to say with the last part because Ruby works quite differently to Lua or Self here and Self has been "fast" for 30+ years anyway. Is this supposed to reflect in R…

It does? JRuby 9.2 can be 15% (web), 25% (optcarrot), maybe 3x faster (microbenchmarking iterators) than CRuby depending on what you're doing. Did you mean messages? They're certainly a central part of Self.

[deleted]

Re: How to Fix Slow Code in Ruby

#177

Earlier quoted context omitted.

Well, you likely have a dedicated (or pretty strong) server. The Heroku dynos I've tested with some years ago performed quite horribly. Only a proper Xeon server was able to achieve sub-100ms responses. But hey, if Ruby improved in the meantime, cool.

Rails on Heroku is about the most inefficient combination you can get for a web server. I've always thought of it as the platform you use for running toy apps with maybe a couple of dozen users at most and a low load. It's incredibly quick and easy to get a Rails app running on Heroku, a couple of hours at most. But you pay (in dollars and performance) for this.

You'd be surprised. I know companies paying $2000+ a month for Heroku and are still having performance problems with Rails.

(Then again, they have them with Phoenix as well but to a lesser extent.)

Re: How to Fix Slow Code in Ruby

#178

Earlier quoted context omitted.

People used to think JavaScript was too dynamic to optimize, too. Then people poured time and effort into it and now good JavaScript virtual machines can hold their own against competing implementations for other languages.

...While still not being multicore. I feel that those efforts you mention don't go far enough. And I am pretty sure backwards compatibility will continue dragging JS down for quite a long time still as well.

Surely they are, via workers and worklets.

Re: How to Fix Slow Code in Ruby

#179

Earlier quoted context omitted.

> JRuby optimizes method_missing in production right now so there's no need to wait for a tracing JIT. Surely this would reflect in benchmarks? Perhaps there is an even slower aspect of the language manifesting in JRuby.... > I'm not sure what you're trying to say with the last part because Ruby works quite differently to Lua or Self here and Self has been "fast" for 30+ years anyway. Is this supposed to reflect in R…

It does? JRuby 9.2 can be 15% (web), 25% (optcarrot), maybe 3x faster (microbenchmarking iterators) than CRuby depending on what you're doing. Did you mean messages? They're certainly a central part of Self.

[deleted]
Post reply on HN