Hacker News new | ask | show | jobs
by praveenperera 2228 days ago
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 wildly more performant code.

6 comments

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 languages/framework. I think culture is a totally valid performance reason to pick a language. Sure there are faster languages and there are jerks everywhere but on average it seems RoR devs are on average nicer and more collaborative people relative to peers.

There is a just a mindset for wanting to write in a language optimized for developer happiness that dovetails with wanting to be happy and work happily with other people. Ya sure those C++ guys can write more performant code but I know who I want to work next to 8 hrs a day. And who I will be more productive working with.

Also I don't think there are plenty of languages that are Ruby/RoR peers. Django doesn't come close. JS ecosystem is a dumpster fire. Some functional and JVM languages maybe but they often come with a corporate culture that kills their benefits. Kotlin would be my bet I guess?

Also if scale is your issue and rails isn't cutting it then you need to go to a proven language with a proven and hirable developer base. That rules out a lot of new and promising languages. Sure they might be just as productive languages but they are resource constrained at the people level. It is really hard to hire Elixir/Phoenix devs etc. You need a talent pool of thousands. Also you need to KNOW the language will be there with a community in 10 years and that it has a history of evolving without screwing over the community. I guess Twitter going to Scala would be an example of this, from my understanding it doesn't solve all their problems.

Total aside: plenty of language need massive tuning to work at scale but it seems like Ruby is unfairly singled out if someone does "exotic" tuning of it but if someone tunes a JVM language or invent their own it is supported.

I don't think Dropbox use/d Rails. But you can add Gitlab to that list which is a VERY good company.
> Also you need to KNOW the language will be there with a community in 10 years and that it has a history of evolving without screwing over the community.

I don't think this is true at all. Where was Rails 10 years ago? It was pretty bad compared to today's Rails. If the Rails 2 and Rails 3 rewrites never happened then RoR likely would've been superseded by something else and be "dead" today. The point is that Stripe, Github, etc were all early adopters of Ruby and accepted that risk

> You need a talent pool of thousands

I also don't think this is true. You need to hire the right people and you need for them to stick around. And you need to be in the right line of business obviously. Again most of the companies you listed were small/passionate/scrappy for a long time

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 learn from years of usage and no clear documentation of when / where features came and went.

All in all every Ruby dev I’ve worked with across 4 companies have all had the same sort of elitist / pretentious attitude compared to Python, Go or Java devs. Ruby has only been second to Scala and Rust devs (so far).

Seems like you're comparing between languages that end up being the default choice due to their low learning curve (Python/Go/Java) and languages chosen because the default choice wasn't good enough (Ruby/Rust/Scala). The latter tends to be much less restrictive or more featureful which necessitates governance by convention/culture/guidelines since its significantly more difficult to be exactly prescriptive over significantly more variance.

For example, most Ruby found in the wild follows some variation found in the style guide: https://github.com/rubocop-hq/ruby-style-guide (same with Scala: https://docs.scala-lang.org/style/ and Rust: https://github.com/rust-dev-tools/fmt-rfcs/blob/master/guide...) and their communities generally care enough to try to enforce it. Most languages have an universally agreeable style guide these days.

I personally find the first set of languages to be more consistent syntactically (typically because they're simpler languages that have auto-formaters) but the latter set of languages are extremely consistent in patterns/ideologies. It seems like you care more about the former and didn't care to learn about the latter (which I'll admit, does present a higher learning curve and tends to be acquired through experience with the community than through a doc).

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.

> 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.

> 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

So which ecosystem is more productive then? What you just described is horrible for a company like Shopify; they aren't a 3 men team working in a garage. And even for a small team, why would you wanna chase a crazy ecosystem like that instead of focusing on your actual product?

I think that it can be a productive ecosystem if you have experienced technical leadership that's proactive in keeping things up to date. If you spend a bit of time every month or two keeping your dependencies up to date it's not too painless, but if you neglect it for years, then it's an absolute pain to update.

I've discovering this the hard way as I slowly upgrade our front end from AngularJS 1.4, no transpiler, gulp, and bower. Almost much nothing has been upgraded in 5 years, which is like 50 javascript years.

JS is not a great language to use if you're an independent beginner, you either have to follow a tutorial blindly to get a boilerplate setup and hope that in the 6 months since it was written nothing has changed in the libraries used and the tutorial is out of date, or you can spend hours learning how to structure a JS app.

I feel like I'm being harsh on JS. Ruby/Rails is an incredibly productive ecosystem for a beginner, but has the same problems with maintainability and upgrading if you neglect it too.

Any framework isn't productive when you're in greater technical debt than the Weimar Republic, and it's easy to write bad code in any language if you're lacking experience. Upgrading dependencies in any ecosystem is difficult if you don't touch your gemfile or package.json in half a decade. I've had the same problems upgrading our Rails app as our AngularJS app, I'm just much more qualified to handle them.

There were also no experienced Ruby/Rails or JS/AngularJS developers at my work until I joined (and there's still no experienced JS devs), and we've always been pushed to ship features, not improve performance or keep our dependencies up to date, so I've had limited opportunities to work on fixing technical debt. Not entirely sure why you'd create a product with two frameworks none of your employees have any experience in. On the plus side, with all this spare time I've had during lockdown, I've managed to make good headway in resolving a lot of that debt, beats spending my days watching Netflix or playing video games.

How about Elixir/Phoenix?
I don't wanna answer for Shopify because I don't work there, but: 1) Shopify LIKES Ruby. The founders love it. You don't drop this after 15 years to gain 20% more speed. 2) Rewrites are hard. We're talking about millions(?) of lines of code 3) Their teams will have to adapt to a new language 4) Maybe 10 years from now a faster language appears - do they do a rewrite yet again? 5) Optimising things is a part of what we do as developers and even love to do. Is it unheard of to try to optimise your code in java? 6) > there’s plenty of languages out there that developers can be just as efficient in. That was always the case. Rails devs still believe (for the most part) their framework is productive and fast enough.
I agree for Shopify a rewrite would not make sense.

But I think writing new features, or rewriting some critical paths of the codebase in a new language could make sense.

It's atleast a valid question.

They are clearly already spending a lot of resources optimizing Ruby code to match their demands.

My question is at what point does continuing with Ruby become trying to force a round peg into a square hole?

They're still mostly a Ruby monolith afaik, so you can't add new features in Go on top of that. Each company and what works for them.

> They are clearly already spending a lot of resources optimizing Ruby code to match their demands.

I think the work on Graal is a VERY long term investment. They can grow to become a 200B company even if none of that work succeeds. Also, I think it's just one guy Shopify is hiring to do that but I may be wrong, so definitely not a showstopper for Shopify :)

Why do you consider Ruby to be inherently slow?

I don't see why that would be the case. In fact, the performance improvements during the 2.x era seem to indicate the contrary: that Ruby can be faster.

> I don't see why that would be the case

Well, the extensive use of “method_missing” appears to be staggeringly difficult to optimize short of a tracing jit and it’s also the core idiom of many popular frameworks. Of course it can be faster—if you remove the slow, unique features you can optimize it like any other language.

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: I’d like to further note that other languages use similar features (string-keyed functions) but they aren’t typically put into high performance code/are seen as a hack around formally definitions (possible exception: common lisp, although I would expect a macro). This is inherently a readability improvement over manually defining the methods you use.

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.

> 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.

Hi,

I'm the Manager of the Ruby and Rails Foundations team at Shopify.

We are investing a lot on R&D for CRuby as well.

We have 6 people working full time on Ruby implementations, both CRuby and TruffleRuby. Not only Chris Seaton is here, but we have two CRuby Core members as part of the team, Aaron Patterson being one of them.

> 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.

>> Of course it can be faster—if you remove the slow, unique features you can optimize it like any other language.

And at some point you might as well use Crystal if you're going to do that, while keeping a Ruby-like syntax.

Shopify is an insanely huge e-commerce platform (and a $100B company). I'd say their developers are pretty productive with Ruby on Rails.
Yes, and at the time Shopify was started Ruby was likely a very good choice. The parent comment is saying that today there are alternatives that run faster and provide similar levels of productivity.
> Shopify is an insanely huge e-commerce platform (and a $100B company).

That's an interesting note. They have a $90b market cap, trading at ~53 times sales. It's one of the more extreme valuations I've seen in the last 25 years, including the dotcom bubble (and that's saying something with how overvalued everything cloud-related is today).

As one comparison for the absurdity, Yahoo during most of the height of the dotcom bubble, was trading for 30-50 times sales, growing sales faster than Shopify, and they were solidly profitable (Shopify has never earned a consequential profit in its history). That's how bad Shopify's present valuation is, to get good comps you have to reach into the dotcom bubble.

The market thinks they're Amazon-like. The problem is they've never demonstrated any great margins in their platform (despite 14 years and counting) and Amazon's big lift-off in their stock occurred solely due to the ability of AWS to generate immense operating income. Without AWS, Amazon eventually gets the sad multiples of a Target or Walmart on their retail business.

This is an obviously mistaken valuation riding one of the most overvalued markets in US history, one that will most likely brutalize investors that get in late. It's a classic example of how very inefficient and irrational the stock market can be in the shorter term. And no, that doesn't mean an investor should be the fool to step in front of the irrationality train and short it either (everyone here probably has heard the Keynes line about the market remaining irrational longer than you can remain solvent).

It'll take at least 10-15 years at a minimum for Shopify to grow into its present valuation, in the best case scenario, if everything goes perfectly and they some day find some margin in their business. If they eventually manage an enormous $2 billion profit ($1.7b in sales today ttm), they'll still have a 45 PE ratio at today's valuation. That's a prime market example of insanity.

eBay has a vastly superior business (in all regards, including its quasi-monopoly positioning and the tremendous profitability of ebay's platform), trading for a huge discount to Shopify, on the basis of the market's mistaken extrapolation about Shopify's future. If they're lucky, they'll one day be the size of eBay with a fraction of the profit margin (and of course eBay has a mere $29b market cap, 12x op income multiple; compression is a killer). I mention eBay (beyond obvious reasons), because Shopify is likely doing nothing more than pulling future returns forward to an extreme, as eBay once did (leading to a decade of stagnation in the stock).

They are probably overvalued. But they have a great product worth tens of billions and will eventually get earnings in line with their valuation. I wish I bought that stock years ago. No, wouldn't buy it now indeed.
You’d have to compare them to an equivalent shop in the same market of about the same size with a different stack to get a meaningful answer out of this—I’d say off-hand that it’s very unlikely their edge is tech.
You only need to be more efficient than the competition, and there’s a shared incentive to push out products faster than you can maintain existing ones. Over the long term it never makes sense to use ruby; only in the short term when it provides a marginal improvement over the competition does it pay off.