13 ms·
Ruby vs. Crystal Performance
- ukd1 6y agoA massive point for me missing in this article is the experience of having to wait for Crystal to compile - especially for development, this sucks. Try timing puts "Hello, world" on both: ~ % cat test.rb puts "Hello, world" ~ % time ruby test.rb ruby test.rb 0.03s user 0.05s system 25% cpu 0.312 total ~ % time crystal run test.rb Hello, world crystal run test.rb 1.48s user 1.09s system 72% cpu 3.559 total
- ptcodes 6y agoThe test was against compiled Crystal code: crystal build program.cr ./program
- moonchild 6y agoI wonder if it would be possible to write in a common subset of ruby and crystal, and use the former for dev and the latter for prod?
- coder543 6y agoI find this perspective kind of funny, because every medium-sized Ruby project I've worked on takes 10+ seconds just to load and start rspec (before it runs any of my tests) or a REPL. Because of this, working with Ruby is actually substantially slower than working with a similarly sized Go project, in my experience, even though Go theoretically has the disadvantage of needing to compile things before running them. Plus, Go's type system will catch tons of bugs that Ruby optimistically treats as "maybe you meant to do this". Obviously Rust's type system is really awesome, but Go's is still really helpful, while compiling much faster than Rust. Since Rust and Crystal are both LLVM-based, I would guess that Crystal's compile times also tend to be a bit painful on medium-sized projects, like Rust, but I've never actually used Crystal for anything more than "Hello, World". (I've been paid to work full time with Ruby, Rust, and Go over the years, and they each have pros and cons, but I just don't think I would ever personally choose Ruby for any new project in 2020, if I had a say in it, given how great Go is for web development.)
- bovermyer 6y agoComing at Crystal from a Go and PHP development background, here are my thoughts: - The syntax is lovely. No, really. - I hate waiting for it to compile, especially compared to Go's compile time. - It's really young yet, and the ecosystem is just getting started.
- ryan-allen 6y agoThe macros are really cool, too. https://github.com/luckyframework/lucky/blob/master/src/lucky/tags/base_tags.cr https://github.com/luckyframework/lucky/blob/master/src/luck...
- tluyben2 6y ago> - The syntax is lovely. No, really. Matter of taste; I find it horrible, just as I find Ruby syntax horrible. And I do not care about syntax too much generally (among my production langs are k and clojure) but I find this an eye sore; don’t know why but it is what it is. Edit: aaah downvotes for an opinion :) Anyway, background; I maintained a huge Rails codebase for years; it was pretty much the worst thing I ever did (in 30 years of production coding) and that was pretty much down because how much I don't like the syntax. That doesn't happen often.
- iomcr 6y agoRuby syntax's alleged beauty is one one of its most popular features and you're in a thread about a language that intentionally copied that feature.
- bovermyer 6y agoFor what it's worth, I thought your comment was reasonable given the discussion and upvoted it. You're allowed to hate Crystal's syntax. I'd be curious to hear why, though.
- mekster 6y agoI don't like rails either but I like ruby syntax. You're sure you don't like ruby and not rails? You got downvoted for not liking something "just because". (I didn't downvote.)
- G4BB3R 6y agoI really liked Crystal some years ago, even used in a prototype. Soon I realized that despite its cute syntax and good performance, coming from Elm, I would prefer a simpler language with type safety, good error messages and very fast compile time. Maybe in the next years I'll experiment again, especially due to Lucky web framework.
- BeKindAndLearn 6y agoMay I ask what language you decided to move to instead?
- G4BB3R 6y agoIn my current job I use Node/Koa with Js, and I am not happy with it. Every side project that I start I use Elixir, and I plan working with it next year, or maybe with Clojure. It's not exactly what I was looking for, but while I can't find one that matches the criteria in the next years, these are pleasant options for me.
- choxi 6y agoIf `brew install crystal` is taking more than an hour to complete, in my case it was because llvm is a dependency and for some reason it was trying to compile it from source. If you manually install a precompiled llvm (you can do `brew install llvm` with some flags) it should skip that step during the crystal installation.
- AlchemistCamp 6y agoI installed crystal almost instantly with ASDF. Just: asdf plugin-add crystal https://github.com/asdf-community/asdf-crystal.git asdf global crystal 0.34.0 It was painless. Other languages I've installed with ASDF must have had the same dependencies.
- kotutku 6y agoI would like Crystal to include some modern features instead just being a fast and nice language. How about stuff like: immutability, good functional programming support, complex union types, compile-time guarantees?
- brokencode 6y agoCheck out Crystal’s official website sometime to learn more about its modern features. Crystal doesn’t have immutability, but does have support for functional programming and union types. “Compile-time guarantees” is such a vaguely specified feature that virtually all programming languages have that, but its type system is actually pretty strong despite how it looks with all the type inference, and even prevents null pointer exceptions unlike a lot of static languages. It also has a lightweight threading system that makes it work well as a web server. Not quite as elegant as something like Elixir, with its isolated processes, but still nice. It also supports macros, which can make the code a lot more elegant and performant compared to similar languages.
- frizkie 6y agoI'm excited to see Crystal grow - I think it has a lot to offer. I know it's not an intended consequence or a goal of Crystal's development, but you'd be surprised how easily plain Ruby maps to Crystal's syntax and method name choices. It can come in handy when you're looking for an easy performance boost.
- remmargorp64 6y agoActually, I would argue that mapping Ruby's syntax and method name choices to Crystal has been a major goal in Crystal's development. It's practically in the tag line for the language, "Fast as C, Slick as Ruby"
- mhd 6y agoCrystal is quite interesting, but a fib benchmark?
- WJW 6y agoI mean it's kinda trivial but it does have the added benefit of also showing off that it's statically typed. For a more real world example check out the website of Kemal (Crystals Sinatra equivalent) at https://kemalcr.com/ https://kemalcr.com/, where it benchmarks at ~46k requests per second in a HTTP benchmark vs 4k in Ruby.
- ksec 6y agoOr something like Sidekiq in Crystal [1], which was 7 times faster. But now I wonder how much faster would Sidekiq run on TuffleRuby. [1] https://github.com/mperham/sidekiq.cr https://github.com/mperham/sidekiq.cr
- WJW 6y agoI'd be amazed if TruffleRuby could beat Crystal, given the problems most JITs have had with Ruby. By restricting the extreme dynamism of Ruby a bit, Crystal can allow for optimalisations that no Ruby implementation will be able to match. It's just really difficult to properly compile languages where it's possible to dynamically redefine the + operator based on input from HTTP requests. That said, Truffle is looking super cool and Crystal does not have anything near the size and quality of the Ruby ecosystem yet.
- deleted 6y ago[deleted]
- zucker42 6y agoThe recursively written Fibonacci benchmark is terrible for comparing a interpreted language to a compiled language. When compiling with optimizations in C, for example, the compiler significantly transforms the program. [1] It's possible Crystal does too. [1] https://godbolt.org/z/vaESBG https://godbolt.org/z/vaESBG
- eeereerews 6y agoRecursive fibonacci is highly artificial, but the fact that a compiler can greatly transform the program is an important advantage of compilers over interpreters.
- zucker42 6y agoI had the (mistaken) impression that the GCC code signicantly transformed the algorithm because there is only one recursive call instruction, but looking at it closer it's still exponential. I still think it's a pretty silly idea to use such an unrealistic benchmark. Especially since it might be possible to make a compiler turn the exponential algorithm linear.
- nv-vn 6y agoI'd be very surprised if there's a commercial compiler that would automatically optimize this into linear time. Maybe some obscure functional research language? But certainly don't think LLVM is capable of dynamic programming.
- ken 6y agoThat's sort of true, in the abstract, but it wouldn't explain what's going on here. Even JavaScript (with a JIT, but not a separate compilation step, and certainly no type annotations) is faster at this than compiled Crystal. There's clearly other factors which are much more significant than simply having a compiler.
- mumblemumble 6y agoWhen you're doing something like writing your own routine for calculating fibonacci numbers, perhaps. But that's not the kind of optimization that's likely to be significant to most developers writing business applications. I would also argue that the ubiquity of things like BLAS wrappers largely blurs these lines. For example, one of the big reasons I choose Python over Java (my company's primary language) for my work is that, thanks to numpy, Python absolutely smokes Java at crunching numbers, for my purposes. This despite Java being a compiled static language and Python being an interpreted dynamic language.
- mauricio 6y agoHere are thorough benchmarks of Crystal and C up against other interpreted languages: https://github.com/kostya/jit-benchmarks https://github.com/kostya/jit-benchmarks. It has other examples besides Fibonacci.
- tmikaeld 6y agoI'm quite surprised to see Javascript / Node so high up the ranks, quite impressive the amount of optimizations that's been done to the engine throughout the years.
- nicoburns 6y agoYeah, a lot of people don't realise that JavaScript performance is closer to Java than Python, even though the semantics are much closer to Python.
- qeternity 6y agoWe recently finished our first node backend (typescript) and I have to say it was an amazing experience. The npm ecosystem definitely attracts its fair share of undesirables, but I struggle to see why JS full stack isn’t the default for 99% of people.
- joelbluminator 6y agoLots of people are sure their stack provides an amazing experience, for example I don't get why you would choose node over rails. As for the performance: looks good for js, but quite a memory hog or am I missing something?
- throw_m239339 6y agoIf all you are doing is writing API then you already don't need 50% of what Rails provides. If you are not into ORMs then you don't really need anything Rails provides at all.
- jimbob45 6y agoWhat’s the elevator pitch on Crystal? Seems like typed Ruby with performance considerations.
- Trasmatta 6y agoExactly, it's basically statically typed, compiled Ruby with really good performance. Also it has really powerful type inference, which allows you to write really Ruby-like code while maintaining your static typing. The downside of that is that it makes the compiler kind of slow.
- ngngngng 6y agoDoes go-to definition work in crystal? That was always my least favorite thing about ruby, I find it very awkward to write code without being able to jump to definitions.
- gavinray 6y agoThis is the reason why I have to keep IntelliJ Idea Ultimate/RubyMine laying around. I don't have the greatest laptop, and run a lot of containers, so Jetbrains IDE's are generally a no-go for me and I stick to VS Code, but trying to develop Ruby/Rails without a Jetbrains IDE Is crippling. I think ctrl+click definition jump does work in Crystal and it has a decent language server.
- ngngngng 6y agoThat's good to keep in mind, I strictly write code in vim but if I have to pick up ruby again I'll give those IDEs a shot. I really like the sales pitch of rails, but as someone that almost exclusively writes in modern, compiled languages, it's really tough to adjust to ruby and be productive with it.
- gavinray 6y agoI wrote Rails professionally for a few years back when that was THE de-facto tech for greenfield projects and new startups. At the time, I really enjoyed it, but I'd never written a modern-feeling typed/gradually typed language yet (C#, which I found really verbose and ugly, a lot of pre-ES6 JS and Ruby, some Lua + Python). I would never voluntarily write it again. Ruby/Rails completely falls apart in larger projects if the entire team doesn't stick to best practices + stringent code and doc standards with stuff like YARD or Sorbet. And so many magic, implicit methods injected everywhere. Super happy writing Typescript and occasional Rust/Go now. I thought Kotlin was pretty nice too, the one small project I had to implement in it.
- timon999 6y agoThis article by one of the Crystal developers explains why this comparison is not fair: https://crystal-lang.org/2016/07/15/fibonacci-benchmark.html https://crystal-lang.org/2016/07/15/fibonacci-benchmark.html. > When doing operations between integers, Ruby will make sure to create a Bignum in case of overflow, to give a correct result. > Now we can understand why Ruby is slower: it has to do this overflow check on every operation, preventing some optimizations. Crystal, on the other hand, can ask LLVM to optimize this code very well, sometimes even letting LLVM compute the result at compile time. However, Crystal might give incorrect results, while Ruby makes sure to always give the correct result.
- ksec 6y agoYou may want to edit the link.
- timon999 6y agoWhoops. Thank you!
- htns 6y agoSince late last year crystal made overflow checking the default (https://crystal-lang.org/2019/09/23/crystal-0.31.0-released.html https://crystal-lang.org/2019/09/23/crystal-0.31.0-released....). Dunno how it changed the benchmark.
- chrisseaton 6y agoCrystal and Ruby do not even remotely have the same semantics. They look similar but the similarity is extremely superficial. The extra semantics that Ruby has have a massive impact on performance, for even the most optimising implementations. This is not a reasonable comparison if you do not consider the 'slick as Ruby' part. No runtime metaprogramming! The entire Ruby ecosystem is built on runtime metaprogramming! (Crystal is a fine language and compiler - but it's nothing to do with Ruby.)
- choxi 6y agoIt has macros at least: https://crystal-lang.org/reference/syntax_and_semantics/macros.html https://crystal-lang.org/reference/syntax_and_semantics/macr...
- watzon 6y agoCare to explain more? Having been using Ruby for about 8 years and Crystal for about 4, they actually have an extremely similar syntax and are also semantically very close. To the point where many Ruby scripts are completely valid Crystal, or at the very least require only a few changes. I do think that people trying to compare Crystal to Ruby kind of miss the point though. Ruby as an interpreted language, even optimized with JIT compilation, will never match the performance you can get out of a true compiled language. By the same token, Crystal as a compiled language will never be as quick to develop with since you have to wait for your code to compile after each change.
- nickbauman 6y agoYeah how fast is that compiler? If it's just another compiled language (rather than the kind of wicked fast compiled language like Go), my enthusiasm will be dampened...
- nine_k 6y agoIf it has reasonable incremental compilation, it can take a few seconds to compile. With good code structure, I see large Java projects compile small changes in seconds, even though compiling Java used to be a hog. You don't often rebuild from scratch during development, do you?
- deedubaya 6y agoI really like Crystal and have had good success using it for web stuffs. I still reach for ruby first, because the dev feedback loop is a lot faster and the ecosystem is more vibrant. The biggest gain I've found in using Crystal vs Ruby is reduced memory usage. Most often my code isn't slow because of the language, but the data access behind it, so counting CPU cycles is less of a priority for me.
- kipply 6y agoI think language-to-language comparisons are often "unfair". Comparing Ruby and Crystal is probably not much better than comparing Ruby to C. Syntax is not an absolute signal for language similarity, and the most important parts of Ruby (in my opinion) more or less require it to be interpreted and not compiled. One can always make languages look the same (which Facebook did with OCaml <-> JS transpiler) without the languages being similar by other measures. tl;dr "yes, that one is faster and looks similar to the other one so our developers will be less scared and this is good" is important and valid but "that one is just the fast language but slower" is not a valid comparison, which I'm kind of getting.
- devmunchies 6y agoNeat seeing crystal on here. I built my startup using crystal and now I write crystal full time. I’m still only using a single dedicated server with a SQLite database.
- cutler 6y agoWhy SQLite?
- devmunchies 6y agoThat’s how I started it. I didn’t want to start a company with a complex setup. The whole service runs on a single machine so it’s very fast and simple. I just back up the SQLite file every hour to s3. Its easy to download that file from s3 to use production data in development. If I start getting scaling problems I’d have to start using multiple servers and at that point I’d need Postgres. But we’re at ~36 employees and 8 figures of revenue on a single server. I can probably go another year or 2 without a big database.
- mekster 6y agoWhat are you trying to ask? Why not?
- ryan-allen 6y agoFull time? Awesome! What is your start up? Are you using a framework? Please tell us more :)
- devmunchies 6y agoWe are a delivery-only cookie company. We process orders online and have lots of bakers/drivers delivering thousands of cookies a week, locally. The backend system processing orders, managing orders records and customers (ERP/CRM), and assigning to drivers is all Crystal on the backend. We started almost 2 years ago and the coronavirus really validated our business model. We don't use any 3rd party delivery services like doordash so our drivers can do 4-6 orders per hour. No frameworks. the only external crystal dependencies are: sqlite3, awscr-s3, and jwt. I was using just crystal template views (ECR) on the frontend but its not maintainable or advanced enough so I'm slowly transitioning everything to Preact. https://cravecookie.com https://cravecookie.com
- cosenal 6y agoSome underrated live coding tutorials on Crystal on this YT channel: https://youtu.be/Q1wOFmt3yng https://youtu.be/Q1wOFmt3yng
- nodefourtytwo 6y agoI knew who it was before clicking. I learnt to love Crystal from this channel. Great content.
- hosh 6y agoThe thing I like about Crystal is that I can generate statically-linked binaries and distribute them. I can quickly build utilities for people to use and don't have to distribute the runtime. The type system wasn't as bad as I thought (especially with type inferencing). Having written Ruby professionally for 14 years, Crystal was relatively easy to pick up. There are a many libraries that hew closely to their Ruby counterparts. There are some amazing things I love about Ruby, like the metaprogramming and monkeypatching ... but I have moved on. I do my server work with Elixir these days.
- tobyhinloopen 6y agoIt’s cool if it looks like Ruby but if it doesn’t run Ruby gems, it’s kinda pointless to consider it a Ruby alternative. Might as well consider Rust or C++
- danielsokil 6y agoHere is a much more fair comparison: Ocaml vs Crystal vs Go: https://gist.github.com/s0kil/155b78580d1b68768a6c601a66f8e29b https://gist.github.com/s0kil/155b78580d1b68768a6c601a66f8e2...
- squarefoot 6y agoCrystal would benefit a lot if ported and packaged for ARM architectures. Those small embedded boards seem the best place to make use of a system language that produces tight and fast native executables. I know there's something for the Raspberry-PI+Raspbian, however I hoped there was an official port for other boards on a more generic distro such as Debian, Armbian or DietPI. Being a bootstrapped compiler (a compiler written in the same language it compiles) makes this even harder to accomplish.
- megavolcano 6y agoHuge ruby ran here. Ruby on Rails has been my day job for a decade, and it pays the bills well enough. Crystal has always been a curiosity to me, but I have never been as productive in any other language or framework as I have been with Rails. I dont' care if you're language is "ruby-like" or "go fast" - if I'm not as productive with it as I am with Ruby, I'm not gonna touch it. Get back to me when there is Crystal on Rails.
- kimburgess 6y agoHere you go: https://spider-gazelle.net/ https://spider-gazelle.net/
- megavolcano 6y agoDoes it also have a massive community and thousands of libraries(rubygems) for almost every possible thing you can possibly think of?
- kimburgess 6y agoIt's a significantly younger language than Ruby, so no, the ecosystem is not as diverse (yet). It is quite populated though - for a taste you can browse at sites like https://crystalshards.xyz/ https://crystalshards.xyz/ or https://shards.info/ https://shards.info/.
- robrtsql 6y agoI'm sure that it's nowhere near as productive as Rails, but this framework is probably best positioned to be the Rails of Crystal, in case you haven't seen it: https://amberframework.org/ https://amberframework.org/
- dzonga 6y agosome of these benchmarks Fibonacci etc are superficial. don't reflect real world use. people need to start comparing languages on ecosystems etc, error reporting e.g Elm | Rust have beautiful error messages. time to write a feature and deployment. Your language | framework could run in microseconds etc but if getting started is a nightmare or it has cryptic error messages, then it's non starter
- pansa2 6y ago> If you recall Crystal is a statically typed language but you can omit explicit type restriction and the compiler will try to infer the type of variable. In our code Crystal uses the Int32 type for the n variable which has the maximum value of 2,147,483,647 but the 47th number is higher. In this case we need to specify the type of n. We can use Unsigned Int 64. Both Ruby and Python use arbitrary-precision integers throughout. I thought Crystal would do the same, given the frequent comparisons to Ruby. I assume the reason it doesn't is to enable AOT compilation (i.e. not only because Crystal is statically-typed)? Is there a statically-typed language that does use arbitrary-precision integers throughout? More generally, what other features are common in dynamic languages and rare in static ones, that aren't directly related to type-safety?
- phamilton 6y agoHaskell has arbitrary precision. JavaScript has fixed precision.
- mumblemumble 6y agoWell, they both have both. More or less. Haskell has Integer for arbitrary and int for fixed precision integers, for example. JavaScript has arbitrary precision integers (via BigInt), and fixed precision floats.
- ksec 6y agoI sort of felt compelled to post this. An OS written in Crystal. [1] Which got quite a bit of discussion last time it was on HN [2] . I know this may sounds strange but I would not be surprised once Crystal reached 1.0 there will be a Ruby implementation written in Crystal. [1] https://github.com/ffwff/lilith https://github.com/ffwff/lilith [2] https://news.ycombinator.com/item?id=21860713 https://news.ycombinator.com/item?id=21860713