profile profile profile before you waste a ton of engineering effort on a rewrite that may buy you absolutely nothing.
The more things change, the more they stay the same!
NewRelic is similar, but I find the TraceView interface much much better.
That said, working against oracle databases with Django is slow as all get out. Something about the driver requires numbers to be converted from number to string back to number, while calculating whether it's an integer/decimal/whatever. Simple queries returning 1000 rows could take ten seconds. I spent several days running that down. The analysts at my shop blamed django, which was pretty unfortunate.
> I heard web applications described as "database skins."
> the slow point in most applications is IO
It's just like how some programmers are 100 times better than other programmers. One SQL query is 100 times faster than another, and both get the same result. And it's not usually something simple like adding a column index. Usually it's a matter of a sub-select or some other squirrelly way of combining tables or aggregating a result.
I wish more programmers learned SQL --- I mean really learned it through and through --- than concentrated on the latest fads.
And miss out on all the coffee breaks afforded by programmers just looping over entire databases in a horribly inefficient ORM ? Because all this condition abstraction in the ORM is really hard to use ...
Don't worry though : they're optimizing it. I hear they're upgrading to run the loop in 100 threads instead of just one. Surely that will accelerate things a lot !
And if that doesn't work, we always have memcache, don't we ? Also we can now use cloud databases to spread the load, surely that'll help (I'm looking forward for the first double-digit page refresh, measured in dollars)
(Having worked years for hosting providers where 20-30% of my job was making PHP/Python/Ruby/sometimes even Java applications run faster, and achieving 50x improvements on a regular basis, this had to get off my chest. And yes I've seen people implement mail address lookups by iterating over the ORM-provided collection ... and then show 50 mail addresses, wondering why the page load time was bordering on 3 digits when measured in minutes. Not even just once)
Edit: More clarity.
This reflects what devs saw in Smalltalk. Business apps ran with sufficient speed on 486 CPUs with interpreters and relatively primitive JIT VM. Business apps were typically bound by I/O to databases and other back-end servers. This didn't prevent bad developers and pointy-haired bosses from blaming Smalltalk execution speed. That was almost never borne out with profiling and where it was, judicious implementation of a particular algorithm in C/C++ usually solved it with a minimum of fuss.
But I think people still underestimate how much development isn't that. Most startups involve things that need to scale now or things that will need to scale. A lot of scientific development need complex algorithms. A significant portion of corporate development needs speed because it's operating at scale or because it's one piece of a long pipeline of import/export applications etc (another portion of corporate development doesn't need speed but good luck finding the discipline to get your manager to distinguish the two cases). And there's embedded and various other things.
"Don't worry about speed, we're just prototyping here" is a saying that always signals danger - a large organization often will want to deploy whatever monster once they know it works.
So really, it seems like Ruby is indeed great for apps for medium-sized brick-and-mortar business wanting a web presence and there is a whole lot of that happening. However, Ruby being inherently slow in multiple dimensions means it's dangerous for many other use cases (dangerous because of the "it works? Why not keep using it" factor and the danger being you'll wind-up using after its slowness becomes a real headache).
I can only answer by parable. Start from the point of view of a group of carpenters asking "is cardboard strong enough to build houses from" and you may a consensus until someone chimes in to say "but a lot of people have made a lot of money selling cardboard houses that survived just long to let them gather investors and money for building real houses." Sure, that may well be true but it's really going to change the view of carpenters.
And that cardboard house provided enough shelter for them to survive and at some point, go to the bank to get a loan for a bigger, sturdier house. I understand that Ruby can be an issue at some mega-scale, I've experienced how slow, memory-hungry and not a concurrency natural it can be. But the thing is, for 95% of the people building businesses, they don't need mega-scale. They just need enough. And Ruby on Rails provides just that. It's fast to build a platform with, it's easy to think about, it has a huge ecosystem and it's worked for a lot of people.
The owners of Twitter never had to worry about the shelter offered by Ruby-on-rails. The original system architect and his team hardly found shelter since he was replaced along with Ruby-on-rails.
From what I see in our perf logs, a faster string concatenation layer in ERBs would be the place where rails could save a lot of CPU cycles, but it really wouldn't matter except for very large tables, and I use intercooler to keep them relatively small w/ ajax paging or infinite scrolling, depending on the UI.
There are plenty of large companies that run Rails and for most up and coming startups Ruby on Rails is probably enough to validate your idea.
I've tried Golang and played around with Node. They're fast, sure. The respective frameworks just don't compare.
Ruby (and Rails) scales just fine for 99.281% of things. You just need to throw money at it.
And that's a great thing.
A business's success will never depend on of the speed of a language or framework. It just doesn't work like that. What matters is how quickly you're able to iterate and evolve a product.
Ruby (and Rails' ecosystem) allows me to not have to reinvent the wheel for mostly everything. Authentication? Devise. ORM? ActiveRecord. Background processing? ActiveJob. Caching? It's there.
Want awesome front-end performance without having to basically rewrite your entire app and learn another framework and manage its dependencies? Turbolinks, and it has matured beautifully.
Basecamp has its performance anecdotes written in history that we can all reference. And Basecamp also has had great success.
Point being is that a business is a business. The speed of a product cannot and should not be blamed for how successful a business is or isn't.
I love you, DH2, and thank you Matz. I love you too.
>> Basecamp also has had great success.
Basecamp is a great SAS business, you can tie utilization to revenue. Throwing money at the scaling problem (horizontal) is completely realistic in that scenario.
If you can't tie utilization directly to revenue, if your a pure service like twitter, or an online store with a bad browse vs buy ratio ruby is a BIG liability.
So is ruby fast enough? It depends. Its a business decision, not a technology one, and one I would have a hard time justifying for a lot of startups.
Last couple of years it's been doing about 50,000 (user facing) api requests per second during high load, with almost a million concurrent users. It's 99% rails.
We (me and a second guy) have ran this system on ~10 (cheap) servers, five of which run the actual rails app.
The rails app has probably been the easiest component to scale for us. We obviously do some caching - but it's not like our database could live without that caching anyways.
And even though we have been an ad-financed bootstrapped company the hosting/hw costs has been very manageable.
There are probably many valid reasons to chose something else than rails, but I wanted to share my experience w.r.t. making it work for our non-SAS needs.
1. profitable? Is it your day job or Side job or a "lifestyle business", Pays for my beer...
2. I would love a number next to cheap ($5? $20)
3. Where are you located, and is that the market your serving.
Because I live around Silicon Valley, my perception of what your saying might be really different from what it actually is... is cheep $20 a month, or is it $5?
2. Per app server we paid less than the cost of a macbook pro. Between 0.001 and 0.0015 USD in hardware costs per thousand ad views, which makes it irrelevant to the company bottom line.
3. Europe, global-ish market.
This is a critical aspect.
If it's purely ad-driven, you probably have very little money coming in for the number of pages you crank out, so you need to optimize them a lot.
If you're charging for your app - which you should be in a lot of cases - then something like Rails is likely ok.
The latter case is much more likely outside of Silicon Valley/VC-fueled startups.
I think it really depends. Many of the most successful businesses thrive purely on ads. Also you'll have to consider which market you're targeting. In the US many people maybe are used to paying a reasonable amount, but in many developing countries people just won't use it if it's a paid app.
Lets say that the gain you realize from writing in another language is 10% of your infrastructure costs. It might not matter day one. At some point that will represent a significant sum of money, in either absolute or relative terms.
Worry way, way more about building the right product at the right price for your customers, and adding the right features.
Computers are amazingly fast these days, but 99% of all CPU cycles go to waste because of this "slow is fast enough" mentality.
A language/framework that helps you figure that out faster is superior to one that is slower to code with. And Ruby/Rails are pretty good from this point of view.
I'll add: perhaps the time will come when there's something that's equally adept at being light on its feet, and is also faster. Elixir/Phoenix look interesting from that point of view. But even there... Erlang is certainly not the fastest thing out there.
This can speed requests up but more importantly it allows you to more easily scale out horizontally.
Is that a fact? I'm not sure anyone has ever shown numbers to back it up. It would be an interesting piece of work to do. I can imagine it's true, but I'm not certain.
I think Rap Genius did a blog post ages ago about being hosted on Heroku, and they said that something like 70% of time was spent inside the Ruby interpreter, not waiting on IO. So modest improvements in the speed of Ruby will have an impact on their bottom line.
What? I've seen tons of profiling posts and articles showing just that thing, and it's the same thing I've also seen forever on my servers' stats. I'm obviously talking about the majority of web apps that are using DBs and doing some kind of CRUD work -- not video processing services et al...
Is that non-typical? Or am I mis-interpreting the graph? (Genuine questions, I've never done any web app operations.)
From the article the slowness is when "a dyno is tied up due to a long-running request" -- so, we they are probably still talking about slow IO operations, and servers running on the dyno that are not async to free it up in between.
From Heroku's one optimization page: "Most applications are not CPU-bound on the web server".
(And Heroku might be an outlier in having high real-cpu use too, as they tend to over-provision).
So if the IO isn't web requests, cache, database or waiting in a queue, what can the interpreter be waiting on? Local files?
In general it's a useful idea that you're likely to be IO bound, because most of the time when something in a new webapp is too slow, it will be database (it may be a small fraction of overall requests, but the ones that hurt) until you have optimized/cached away your database request and are trying to scale further.
Basically once you've solved the "naive"/early database bottleneck, then CPU and memory very quickly becomes more likely to be a cost factor.
For example, there's a painfully slow web application at my company that puts data on a page by doing a straightforward select from a database, and then running lots of nested loops over the data to render the page. It's definitely CPU-bound. If it was written to use a more powerful query, or to use more sophisticated algorithms, it would be a lot faster, and would probably be IO-bound. But it isn't.
That said, in my experience this has been the case when it comes to handling HTTP requests.
Reminds me of this tweet which summarizes Ruby quite well:
There's no doubt that by not fully utilizing modern CPUs it is giving a serious advantage to the future prospects of languages like Elixir which make using concurrency as easy as using Rails or Go, where performance is baked-in. It's not so much about is Ruby good enough but why use Ruby in the long run if there are languages offering similar benefits but with better performance or good concurrency primitives?
Having support for the latter is not a detriment to early stage projects using the languages (this isn't about Java/C++ vs Ruby any more...), but later on lacking it will
* websockets & realtime stuff. (Rails 5 added that, i know, point still valid)
* dev mode experience. rails startup time is slow enough to add bandaids like "spring" in default installation.
* sort of "magic" that actually hurt developers
Seems a bit dismissive. It's not like Elixir/Phoenix have really been mature for all that long either. (Especially if your definition of "maturity" includes a broad selection of userland packages/gems.)
> * sort of "magic" that actually hurt developers
It's not just this comment, but I don't understand why "it's magic and that's bad" seems to have been accepted into the encyclopedia of Facts About Rails™. I still have yet to see a particularly good argument against CoC; it boosts productivity and teaches developers to write concise, consistent, expressive code. All good things in my book.
Rails is great, and I've been productive in it for a long time. But the complexity (some would call it bloat) is real, and there are nasty edge cases. And when you stumble upon one, well, good luck.
maturity is many-dimensional here.
* userland packages - yes, sure. erlang/elixir ecostystem is not mature as of yet. It works, it nice, but you can't find everything you need (including e.g. blog posts and SO answers for every possible question).
* On other hand, erlang base brings stability, instruments to solve every possible _production_ issue out there.
* Phoenix itself is has same mixed aptitude - it's pretty new and, at same time, written by core rails dev and therefore has many design issues fixed from start.
> "it's magic and that's bad"
IMO it's not the magic that hurts but overtwisted internal logic where you can't figure out how it works exactly (and yes, Rails became pretty complicated software). Keeping things simple (at least "mental model" of things) is damn hard :( Phoenix is basically == "rewrite from scratch to reduce complexity and fix things that can't be fixed without starting from scratch"
i like that! Also, both Rails and Phoenix doing it right. 90+% other frameworks failing miserably :(
All of them have optimized and improved their speed since then.
In 2003, it was expected that web pages have a bit of a delay before loading. In 2016, it is not. Ruby has not yet adapted.
Additionally, computers got much faster and have many more cores, allowing for additional process concurrency. This is an argument for me to move to higher level, more abstract languages, not to race back to lower level languages because "they're fast". If anything, ruby/js/python aren't high level enough and could be slower but more productive. I'd choose that over raw performance for the vast majority of my needs.
Additionally, Rails benchmarks might show ~100 hits per second (that's 8,640,000 hits per day per process, do you actually get that much traffic?), but I can get thousands of hits per second running Sinatra. I still think Rails is plenty fast, but it's silly to blame a language for a framework.
Ruby has for years been a victim of FUD, opinions on it's performance that seem to have been derived from fuzzy stereotypes rather than actual information. I think that's what the author is frustrated about, because that's the one thing I'm pretty frustrated about too. I'll be the first person to abandon ruby when a better language comes out for my needs, but I've still never seen it.
However, threads will never help you in an IO-bound system (unless you own some kind of thousand-core CPU with an equal number of OS threads). Threads will simply block at the first waiting IO call until you eventually run out of threads. Node.js from the beginning was built for non-blocking IO, as are several Python frameworks (e.g. Twisted, or more recently, Tornado), thus the need for more than one thread of execution was typically unnecessary (again, provided the bottleneck was IO).
CPU in the web layer is not the bounding issue for most web apps.
Adding a vague "it's gotten faster" is not sufficient to mean that it's fast enough for 2016.
It may or may not have improved enough, but either way this argument does not prove that it has.
There are some technologies that were impractically slow in 2003 but have become 'fast enough' in 2016 either by improvements of tech or just by having more cpu/ram/gpu power - but not the other way around.
Ruby's performance does matter. In 2016 you can't call yourself a language optimized for developer happiness when it takes seconds or minutes (in the case of some Rails apps - Hello routes.rb!) just to start up.
I ask because in mine I start up the application very rarely, say when changing a gem, initialization or configuration file. All other times my changes, in development, are automatically refreshed. Hence I rarely start and stop my development system. Of course I am running my development locally. If you were actually deploying your ENV out to some servers continuously for every change then that would be annoying, yet how much of that delay is do to Rails restarting vs doing a remote deploy....
We've tried to use pre-forking preloaders like Spring but we found ourselves force killing Spring more often than it was useful for us.
EDIT: Performance is complicated and can be a sensitive topic so I'm going to elaborate. While dev restart/refresh times are annoying, the real elephant in the room are Rails test suites. We (and many other places I've worked at) rightfully use our test suite as a signal of when to merge and when to deploy. This means the entire suite (~4000 tests - it's a big app!) needs to come back as passing before we will merge a branch that can be deployed. Our current test suite takes about 40 minutes to run in a single process (more on this later) if the planets align.
Here's a list of a few things I've done in my career (I'm very grateful Ruby and Rails have given me a career, btw) to get around Ruby and Rails' performance gotchas:
- Caching logic so complicated that you would think our business domain is actually caching and not our real business.
- Converted a test suite from TestUnit to RSpec (it was fashionable) and then finally back to MiniTest.
- Stopped writing the type of test that is by far the most valuable (End-to-end browser specs) for all but the most important features due to how slow these types of tests are and the amount of false negatives they produce.
- Tried the whole shared_connection.rb trick to share a DB connection between feature spec thread and Rails server threads for transactions in feature specs. It's buggy and made our test suite worse off.
- I've gone back and forth between PhantomJS and capybara-webkit more times than is healthy.
- Wrote code to spoof the User session in the above tests so we didn't have to browse to login_path all the time.
- Set DEBUG_ASSETS to false in development (except for when we're editing CoffeeScript files) to reduce the amount of work that sprockets need to do.
- Used our hosted CI's parallel test runner to try and run things faster. Marginal improvement, proprietary, and lots of yucky config files.
- Used Aman Gupta's test-queue to parallelize our test suite under our own control and now we're looking for automate spinning up instances with 8+ CPUs to hopefully get our test suite to run in less than 5 minutes.
0 - https://gist.github.com/josevalim/470808
1 - https://github.com/tmm1/test-queue
You'll notice this does not pick models with far higher core counts. The per-core performance growth may have slowed, but it certainly hasn't stopped.
> Ruby's performance does matter. In 2016 you can't call yourself a language optimized for developer happiness when it takes seconds or minutes (in the case of some Rails apps - Hello routes.rb!) just to start up.
Don't blame Ruby for the complexity of Rails (to be fair, it's not just Rails - a large part of the problem is bundler which happily piles stuff in the load path that causes startup times that grow exponentially with the number of gems)
In my current company, we also haven't moved to Docker. A few people use it for a few things, but I'm not running it yet myself. Definitely not a universal, and I'm actually kinda unsure where to get started with it in my daily workflow.
I put this down to Apple more than Ruby, though, since Linux support hasn't let me down in the same way.
It is not harder to install ruby than it has been.
`gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3`
`\curl -sSL https://get.rvm.io | bash -s stable --rails --ruby=2.2.2`
It literally doesn't get easier than that. Need Postgres? Postgres.app. Need redis? Probably will install brew anyway, and then `brew install redis`
I'm not seeing OP's argument here. Sure, it's not PHP where zillions of shared hosts are abundant and you can just upload stuff via FTP, and there's no cPanel/DirectAdmin or Fantastico/Softaculous for your WordPress deploy.
But that's a different segment of a similar-but-not-same market.
If nothing else, I think reminding people that what they're "looking to do" (whatever that is) most likely is something they can do in whichever language they choose, and to somehow shoehorn themselves into a language or a set of languages, not because they have a concrete need to, but because they think they might need to... (Once they start... If they ever get going on it...) is foolish and really does not contribute to execution.
Sometimes it's better to get going in the most productive language you can find for the problem space and make a slow/inefficient implementation with few lines of code, minimizing the risk of bugs, (call it "MVP" or whatever) if only to find out whatever it is you're trying to do. Most languages without suffocating boilerplate will do just fine for this, regardless of their performance.
If performance alone is important to you (rather than many other considerations like ease of coding, library ecosystem, number of developers who know the language) - you'll almost always do better with compiled languages - especially those with good concurrency support. But the power of many of the dynamic languages is that they provide an ease of coding that reduces the cost of development significantly, especially for earlier stage companies where the benefits of performance may be less important than other considerations.
For many teams I've seen, you can also rewrite the most computationally heavy parts using FFI, allowing you to have the benefits of dynamic languages without some of its disadvantages for computationally heavy work (though it comes at a cost of adding a new language into your stack).
I say this teasingly, but you may want to rewrite your slow Golang codebase to see how much faster performance you could get with C++ (but again, it comes with a cost to your development team - and only your team can decide what tradeoffs to make given the stage of your product/company).
But my original point is that performance shouldn't be the primary characteristic you measure a language or framework on, unless it is absolutely critical for your needs and you're fine with the other disadvantages that might bring.
Maybe it's the way the programs are written.
For example, binary-trees Go #6 program is no longer shown because it doesn't do what's required.
Would you have written the app originally in a different language(s) or framework(s)? Or is the approach you chose (start with Ruby then selectively refactor), the approach you still would have taken given all you know now?
The same cannot be said of languages like Java, C#, C++, C or Rust, for different reasons.
Java has the bureaucracy I mentioned and that expresiveness you speak of is often the biggest creator of technical debt which specially shines when someone else has to work with your code and understand all your different abstractions.
As far as tooling goes, what are you particularly missing from the Java ecosystem? Honestly I have big gripes with Java's tooling, most important of all the language's hard-dependency on big IDEs to get anything done.
You're quite right about expressiveness being a double-edged sword. I've been lucky enough to mostly work with programmers with the judgement to use it well. I don't think that's rare, but it's not universal.
The tools I'm missing are sane dependency management, and automatic refactoring. Any language where I don't have good automatic refactoring is going to be slower to work with, no matter how wonderful the language itself.
MakeSureToGetItInPrint importantThing = new Namespace.MakeSureToGetItInPrint(one, two, three);
As for automated refactoring, what more would you like to see in the tooling compared to what you already have (renaming)? The death-by-thousand-file-splits that's recommended in Java and for which IDE help is useful, is not idiomatic in Go. The most code you have to write to split a file into two is the keyword `package` and the package name. The rest is just copy+paste and let `goimports` take care of doing the rest.
Automatic refactorings i routinely use in Java are extracting variables, methods, constants, and fields (including automatically finding and extracting repetitions of the body); inlining the same; splitting and combining variable declaration and use (easier in Go, of course!), adding, removing, and reordering method parameters; correcting declared method return and parameter types based on actual use; extracting superclasses and moving methods up and down type hierarchies (again, not relevant in Go); moving methods to a receiver which was one of its parameters. All the stuff which is the bread and butter of reshaping code. All done in a keystroke or two. Not copying and pasting and then manually following through.
Again, to be clear, i have done Go development. About three months of full-time Go with experienced colleagues. I know what state of the art Go development looks like. It's unambiguously slower than Java development.
We'll have to agree to differ on dependency management.
Because I've had to deal with that type of shit before. Java might have a history of AbstractBuilderFactorySingletons, but you'd be hard-pressed to find an IDE that couldn't make quick work of it. Monkeypatched at runtime? Good luck!
Forking a gem is preferable to monkeypatching, but sometimes this can lead to a chain of forks just to change one line in an indirect dependency, worse than the patch.
No, the worst thing is method_missing. Methods that appear nowhere in the source getting invoked, and they only appear at runtime. You can do similar things with InvocationHandler in java but it gets used far, far less.
Misbehaving classloaders sounds like a straight up bug, or a lack of standardization around how a classloader should work. That doesn't sound so much like a failing of the language itself, but again, Java isn't my primary language so I'm not entirely privy to the landscape of Java fuckery. :)
That said every Rubyist should be following Chris Seaton's work chrisseaton.com/rubytruffle/deoptimizing/ with JRuby Truffle+Graal. This is our best change, imo of course, to make Ruby fast.
It proposes a very interesting path for Ruby to get way faster, without resorting to the JRuby implementation.
Basically what he's proposing is we could compile all the Ruby Stdlib ahead of time to a LLVM kind of bytecode.
Once you do that, a JIT compiler for Ruby code could perform a way deeper optimization, because the compiler horizon-line will be stretched much further away: the compiler will be able to inspect the Stdlib bytecode and make optimizations to your Ruby code taking all that into account!
This could be a revolutionary approach for MRI, please go see the talk, it's really interesting!
For example, the Ruby interpreter never returned dealocated memory to main, it just kept anything deallocated by a program in it's own memory - copy a huge file between machines, wind-up with a
The head of operations of Twitter told me that at one point they were starting and killing ruby processes every minute because of Ruby's huge memory appetites and they not only had to throw huge amounts of hardware at the problem but also throw huge amounts of electricity to keep with the CPU churn.
Ruby can't defragment memory pages - if there is an active object in any heap page, it cannot be released back to the OS. Technically, Ruby does release empty pages back to the OS, but in practice, heap pages are rarely completely empty.
This doesn't need very much memory.
Sadly the core Ruby team has been incredibly indifferent and at times outright hostile to projects like JRuby and Rubinius that have tried valiantly to push Ruby forward.
> At RubyConf 2015 in San Antonio, Yukihiro "Matz" Matsumoto announced Ruby 3x3. The goal of Ruby 3x3 is to make Ruby 3 be 3 times faster than Ruby 2.
That's speaking as someone who works full time on optimising Ruby, and wrote a PhD on it.
I think the one hope is that Evan Phoenix suggested an idea that would let an LLVM JIT optimise through the Ruby implementation, but this is a full-on research project (he said it wasn't, I'm not sure I agree), and nobody is working on it.
Basically what he's proposing is we could compile all the Ruby Stdlib ahead of time to a LLVM kind of bytecode.
Once you do that, a JIT compiler for Ruby code could perform a way deeper optimization, because the compiler horizon-line will be stretched much further away: the compiler will be able to inspect the Stdlib bytecode and make optimizations to your Ruby code taking all that into account!
Their greatest legacy, the incredibly comprehensive Ruby Test suite, seems to be largely ignored by the core team which is a true shame. http://rubinius.com/2014/12/31/matz-s-ruby-developers-don-t-...
What's the work done on Python?
Releases like Python 3.6, where lots of little optimizations are made, give Python a performance growing edge on Ruby.
Those Python 3.6 enhancements are still going to result in CPython being absolutely crushed by Python 2.7 on PyPy5.
¹According to entirely unreliable microbenchmarks found via quick web searches.
²Not to knock Tcl. I actually love Tcl. One of the reasons I love Tcl is the ease of extending it in languages with better performance.
Profiling and caching should be the first step to solving an existing app's problems.
Rails is a great framework because it gives developers rules, a simple pattern to follow.
All that being said, if I was starting an app today I wouldn't choose Rails or even Ruby. There are plenty of other options that are almost as expressive and easy to hire for without the speed penalty. If you hire good developers they can get up to speed on any language and any framework. If you don't hire good developers then you're paying a 2x-10x penalty for hiring bad developers and a slower language or framework. Who here hasn't ever worked with or hired a bad developer?
IO is the true bottleneck in most situations but so is a developer writing a view that queries the database for a list of things and then filters them in code instead of letting the database do it. I can't count on two hands the number of times I've seen a developer do this in the past 6 mo.
Your framework and your language are your platform. If you're stuck on a platform, accept it. Rewrites are hard. Hard for the business, hard for your users, hard for your developers. If you're starting from scratch do yourself a favor and pick something that doesn't chop you off at the knees to begin with. Bad code in (Go, elixir, c#, python) is faster than bad code in Ruby.
The performance FUD is probably just deflection.
As DHH himself says, engineers are in short supply - so their preferences tend to get listened to.
The fact that just about every rails performance issue ends in another language is the most telling part of the story. IF your php framework is slow, you might see a BIG speed boost from native PHP, or HHVM, or last resort C. Python has a similar option chain, and that just ISNT there for rails.
Does he mean 2000 rps per instance? If so, that's not bad!
Today, I argue for quite the opposite approach. Select a high-performance platform that is workable for your team and enjoy the luxury afforded by raising your performance ceiling. Rather than your platform and framework creating an unreasonably low and frustrating performance ceiling—wherein you will find yourself fussing with performance tuning and complex system architecture way earlier than you should, use high-performance infrastructure and defer tuning your application for a long time, if not indefinitely.
Performance is an objective measure, but what performance means to you is potentially subjective. For my part, high performance means peace of mind. I can write my application more quickly, using brute-force algorithms and other quick implementation tactics. I can tune my application later, if and when the need arises.
But if my platform is what causes my performance pain, tuning my application is a futile exercise. I am forced to increase my system's architecture and add more servers, load balancers, messages queues, job workers, all manner of things that make my architecture sound awesome to a programmer but do nothing to improve a user experience where pages are still taking 500ms of server side processing to execute trivial operations.
Yes, with enough effort, essentially any platform and framework could service any application's performance needs. Facebook is famously built on PHP, which is not a fast platform (modest in raw form; slow when encumbered with a framework). Facebook has invested untold scores of dollars into tuning. This is what I feel is important to those of us building just average apps: you probably won't have the money and developer bandwidth to actually tune your platform, as Facebook has done with PHP. So you'll scale horizontally and add a lot of architectural complexity and cost. This might more or less work, and you may be successful in spite of the unnecessary complexity. But my opinion is that it's easier and more comfortable to select for high-performance at the start and just defer that complexity; defer optimization.
I find the upsides of Ruby are subjective. "Programmer happiness" is obviously a subjective matter. I personally am considerably happier on a high-performance platform, especially one that is easy to work with. I am not alone.
Thank you to Ruby and Rails for pushing for a lot of great ideas we enjoy on other platforms today. But its performance has never been good enough for my tastes and that remains the case in 2016.
It's important to remember what the web development landscape was like in 2004. PHP, Perl, ASP and Java are all weak languages which I would never choose over Ruby. These days things are condierably different. While I have no great love for Node, there are clear benefits to isomorphic client/server code, and going async-first across the board. Similarly whether it's Go, Rust, Elixir, Clojure or Haskell, there is significant community traction in languages that have order-of-magnitude better performance characteristics, and solve problems of both parallelism and type safety which pay huge dividends in performance and maintainability over time.
I still think Rails is hard to beat for rapid prototyping, and I'm not in a rush to jump ship, but I think DHH is kind of sticking his head in the sand here. Once upon a time it made a lot of sense to pay Ruby's performance tax in exchange for the power and expressiveness of the language, these days I think we're seeing the ascendancy of languages that show you can still have great expressiveness while sacrificing much less in terms of performance, parallelism, and safety.
I'd prefer to avoid the need to scale to deal with a few hundred concurrent users. I'd prefer to imagine my CPU yawning and asking for more.
You may be speaking of very low-traffic systems, and I will agree that with such a scenario, any technology could suffice. But in 2016, we programmers enjoy a lot of options for building web applications and services, including many high-performance platforms that are a joy to work with. Putting aside subjective matters such as existing preferences and experience, if you've got a new project and an open mind, why bother with low-performance when you can have high-performance and ultra-fast response to user requests? To be clear, I'm not saying existing preferences and experience are unimportant. But if you find yourself entertaining the option of using something new, I recommend factoring high-performance into the selection process to enjoy the peace of mind that it brings.
This is funny. The only think I like about writing VBA plugins for Excel is that I get to put my algorithms hat on and go for the optimal solution. I remember bringing one implementation from O(n^2) to O(nlgn) and being blown away by how much better the performance was.
A single load balancer with two identical app servers each of which handle thousands of users is really simple by comparison. You might even have them in cold-failover.
But like I said, what performance means to you is a subjective thing. I personally strongly prefer a high performance ceiling, especially since I can have that while still enjoying a very developer-friendly experience with many modern platforms. There's nothing wrong with big hardware and complex architectures, when you need them, but I'd prefer keeping things simple for modest applications.
All that complicated architecture stuff was driven by business requirements, not by limitations of the platform.
I wanted to state it clearly with no equivocation; fast is relative and Ruby might be fast enough for certain use cases, but not for others.
The applications are pretty similar, but request are processed faster with Sinatra, and small queries are no different, you only note the difference when the query returns more tan 100,000 records, but it is an exception to the rule, I suspect it has to do with IIS modules being more heavy than Thin in Ruby.
The CLR on Windows was/is top-notch. Now, with Kestrel as an option for ASP.NET 5, you're starting to be able to get closer and closer to the metal, so to speak, and eliminate a lot of the baggage required to actually hit your code from an HTTP request.
At any rate, interesting to hear. :)
I can't remember who said it initially, but my favorite sentiment on all this is:
> The only people still using Ruby are the ones making money.
In other words, I think it's a pretty great, stable community of people who use it in production and have seen it all, so to speak. I kind of include Python in this, too- besides the obvious syntactical similarities, I think they are pretty similar in terms of ideology.
I'm in a bit of my third honeymoon with Ruby (and Rails) this summer. I've been seeing a lot of people in the Go community, for example, talk about "just use the http libraries, no one needs a framework" and I think they're fucking bonkers, or at the very least write backend apps with no UI and no more than two contributors on the project. Frameworks like Rails give you so many security, development, and deployment niceties that I have zero interest in rolling my own anymore. (I saw a "screw frameworks" Go talk that spent ten minutes on how to reload code in development, for example... that was a solved problem for me in 2005.)
I'm kind of in love with the idea of writing everything in Ruby (or something similar) and when it makes sense and can be provably improved, extract it out in something like Go or C. The Go+Ruby combination in particular is super attractive to me, and it's likely going to be fine for the foreseeable future, I think.
> The recent post from Parse Engineering Team [...] if you look at GitHub also, the number of Ruby repos are getting lower over these months.
I think looking at these examples don't the whole picture here. GitHub, for example, is a fairly feature-complete product, and their next few years will likely focus on optimization work. If you have a mature product, you have a very clear performance profile of what's breaking, what's fast, and what's slow. That's why GitHub, a seven year old company, is more likely to open source Go libraries at this stage of its life rather than Ruby libraries (for example)- it's obvious which use cases can be targeted for speed, maintainability, and shareability.
Parse is another clear example of this- they have a codebase that they've worked with for quite some time, with obvious spots of improvement, so they switched to Go. If you're looking at new companies that need a fair bit of creativity, product development, and development speed, I think Ruby makes a lot of sense. Premature optimization is not just a waste of time, it's an exponential waste of time, as you might head in a wrong product direction that can potentially sink the entire company.
> I am wondering what's will be the next language gonna rule like PHP. Though there are JS tech is in the peak, I still not convinced to use it on server side. Go and Rust looks promising.
A decade from now, yeah, things may be completely different, but for the time being there's a lot of exciting choices and options happening. Kind of love it.
Perl jumps to mind as an example, and PHP stole its lunch money, and ran off.
Unless you want to be writing ML algorithms yourself.
If that's not the case, maybe you will find this interesting: "TensorFlow is coming to Ruby" - http://www.somatic.io/blog/tensorflow-is-coming-to-ruby
What is fast enough? If you're building a web app, fast enough is not the same as if you're building a web API. The latter needs to perform much better than the former in my experience because the former might make multiple calls to the latter in a single request. I find it almost impossible to make an argument for interpreted languages at this point for backend services considering how slow they are and how few, if any, benefits they have over the many non-interpreted languages out there. I'm thinking of languages like Clojure and Elixir, but even Java has a framework that supports hot code reloading (Play) thus getting rid of the last remaining benefit of an interpreted language. Once you get rid of that, it really no longer makes sense to use an interpreted language, all other things that DHH mentioned being more or less equal.
There are certainly types of code that will be CPU bound, in which case, yeah, there's a good case for using something else - or calling out to something else -, but for large parts of what people write, not being IO bound is a warning sign that you should take a long hard look at what you're doing, because chances are you're doing something silly.
Webapps and typical APIs for webapps tends to be amongst those.
Of the work I've done in the last 20 years, maybe 2-3 projects have been projects where CPU performance have been an issue. For others it will be every project they every do. But the point is there are plenty of us for whom language performance is not a factor we usually need consider.
Expand on this please?
> The main Rails application that DHH created required restarting ~400 times/day. That’s a production application that can’t stay up for more than 4 minutes on average.
Ruby and Rails are nowhere near fast
Is not what's being argued. What's being argued is that "not fast" and "fast enough" are not mutually exclusive. My experience with other "slow" languages (primarily Python) is that this is true; even when the language implementation, or the application stack on top of it, is objectively "slow" compared to a similar stack in another language, often it simply makes no difference because that "slowness" gets lost in the noise of all the other, much slower, things a web application has to do.
I'm reminded of a wonderful blog post from years and years ago that I unfortunately can't find, which showed a pie chart of realistic profiling data from an application -- majority of time spent in things like network I/O, talking to its database, etc. -- and had a tiny tiny little slice labeled "Template rendering". It then pointed out that according to many people (fights among Python templating systems were common then) that was the obvious place that needed to be optimized for performance, ignoring everything else in the pie chart.
That isn't a complaint about performance.