Reducing Memory Usage in Ruby
tenderlovemaking.com
tenderlovemaking.com
The underlying JVM and the Truffle/Graal/SubstrateVM is the product of millions of man hours of research - and for the very first time, you have a compiler framework on top of that.
The Truffle framework also brings in a lot of support that all languages get for free, like zero overhead profiling https://twitter.com/nirvdrum/status/948333404122214401
Truffleruby is already in the running in benchmarks, and it will be awesome to see how far it can be pushed . http://nirvdrum.com/2017/02/15/truffleruby-on-the-substrate-...
It seems right now, TruffleRuby 99% of Ruby code without much problem. C Extension may be the key to wide spread adoption.
I run Ruby with jemalloc, and I know that samsaffron have tried to include it within the Ruby releases (like Redis does), but progress seems to have been stalled https://bugs.ruby-lang.org/issues/9113
jemalloc likely wins more for the kinds of allocations you find in scripting language runtimes, which also happens to be similar to a browser given DOM & JS
Jemalloc implements more complex strategies (per-thread caches learned from tcmalloc, preallocated arenas, …).
It tends to have a somewhat higher memory use than simpler allocators, but have faster throughput and less fragmentation (the latter is why Firefox switched to jemalloc by default IIRC).
> I would expect that would be something worth rectifying unless other requirements tie their hands.
Why? If they consider ptmalloc good enough for their purpose, replacing it would be very low priority, and they may value e.g. code simplicity higher.
Incidentally, there was talk at one point to replace glibc's ptmalloc: https://sourceware.org/ml/libc-alpha/2014-10/msg00419.html
TIOBE index is a junk metric (I'm surprised so many technical people seem to buy into it; it's the worst kind of easy to get a precise number, hard to demonstrate that that number has any more than a very distant relationship to anything meaningful, kind of metric that, IME, tech people mock bad managers for buying into.)
That said, Ruby’s got (via Rails and other web frameworks, and via various testing and admin tools) a very strong footprint in use even if it's no longer the hype-of-the-month.
It’s popularity at this may have diminished with the rise of JavaScript, Go and alternatives but many folks still like and use Ruby, or at least would like to see it continue to improve and thrive.
Similar to general hiring/salary surveys, I’m not sure that the referenced index is accurate.
It also has an amazing testing framework in the form of rspec, which can be used for much more than just testing Ruby code.
TIOBE has it's issues but as a rough guide to what the industry is actually using I think it's in the ballpark.
Elixir is kind-of in the same boat for me. I think it's neat and has its place, and BEAM is really cool, but it doesn't scratch the Ruby itch for me. I just don't care about it looking vaguely like Ruby if it's not actually gonna be Ruby.
For me, everything that Ruby is valuable for is retained. I'm able to do all the things I did in Ruby just fine, and it prevents me from doing a lot of things I shouldn't have been doing.
We recently migrated our app from Rails to Crystal (using the Amber framework) and our code base is now 2/3rds the size and we eliminated hundreds of bugs in the process simply from static typing and explicit nil handling. Our response times are also now all under 30ms where we were at 100ms+ before.
I have Kotlin, C#, C++, and Rust if I need static typing. Ruby is for when I don't.
I occasionally wonder whether it might be possible to accommodate more dynamic language features with a compiler that treats them like a macro system that is expanded statically, such that no actual dynamicism is necessary at runtime.
Plus it is faster than Go/Java/Elixir. As others have pointed out, Crystal does have meta programming capabilities.
[:thing, :other_thing].each do |msg|
define_method(msg) do
@json[msg].to_s
end
end
When this is far more clear and, for me, aesthetically pleasing: def thing
@json[:thing].to_s
end
def other_thing
@json[:other_thing].to_s
end
I'm not sure how you'd use a ruby object that maps to an OpenAPI spec if you don't know what's in the API response until runtime... surely you or the user of your library has an idea what's in the API they are consuming?I full-stop don't do codegen in any project under any circumstance that is not done strictly within the workflow of a build tool (i.e., a Maven generated-sources gizmo). OpenAPI's options are pretty much all exactly not that: all the codegen options's happy paths seem to be vendoring generated code. And that makes me itch, too.
You can build your code at runtime from the spec and then compile it at runtime to get pretty good performance.
I'm also not sure Crystal can implement an active record pattern off of a database? (Though I am not personally the type to go with that, I prefer row mappers.)
https://github.com/amberframework/granite-orm https://github.com/sam0x17/crystal-mongo-orm
At that point, you may (should) just use an object mapper like ROM that has no model-class hooks at all. (Which I actually like. But the Rails world disagrees.)
You're trying to slice too fine. Crystal can't do this. That's OK. Own it, don't try to hide it.
However, that is basically a lookup table using string based dispatch to decide what to execute, and such a lookup table can be done in anything.
Ruby is awesome, as is Elixir, but very different awesome.