サクサク読めて、アプリ限定の機能も多数!
トップへ戻る
ドラクエ3
tenderlovemaking.com
Recently I gave a talk at RailsWorld (hopefully they’ll post the video soon), and part of my presentation was about eliminating allocations in tokenizers. I presented a simple function for measuring allocations: def allocations x = GC.stat(:total_allocated_objects) yield GC.stat(:total_allocated_objects) - x end Everything in Ruby is an object, but not all objects actually make allocations. We can
The Ruby community has lost a giant. As a programmer, I always feel as if I’m standing on the shoulders of giants. Chris Seaton was one of those giants. I’ve been working at the same company as Chris for the past 2 years. However, I first met him through the open source world many years ago. He was working on a Ruby implementation called TruffleRuby, and got his PhD in Ruby. Can you believe that?
Let’s start today’s post with a weird Ruby benchmark: require "benchmark/ips" class Foo def initialize forward forward ? go_forward : go_backward end ivars = ("a".."zz").map { |name| "@#{name} = 5" } # define the go_forward method eval "def go_forward; #{ivars.join("; ")} end" # define the go_backward method eval "def go_backward; #{ivars.reverse.join("; ")} end" end # Heat Foo.new true Foo.new fa
It’s not often I am able to write a patch that not only reduces memory usage, but increases speed as well. Usually I find myself trading memory for speed, so it’s a real treat when I can improve both in one patch. Today I want to talk about the patch I submitted to Ruby in this ticket. It decreases “after boot” memory usage of a Rails application by 4% and speeds up require by about 35%. When I wa
My last post detailed one way that CRuby will eliminate some intermediate array allocations when using methods like Array#hash and Array#max. Part of the technique hinges on detecting when someone monkey patches array. Today, I thought we’d dive a little bit in to how CRuby detects and de-optimizes itself when these “important” methods get monkey patched. Monkey Patching Problem The optimization i
I’ve been working on building a compacting garbage collector in Ruby for a while now, and one of the biggest hurdles for implementing a compacting GC is updating references. For example, if Object A points to Object B, but the compacting GC moves Object B, how do we make sure that Object A points to the new location? Solving this problem has been fairly straight forward for most objects. Ruby’s ga
In a previous post, I wrote a bit about how Ruby objects are laid out in memory. Today we’ll use that information to write a program that will allow us to take a Ruby heap dump and visualize the layout and fragmentation of that heap. Ruby Object Layout Recap Just as a recap, Ruby objects are fixed width. That is, every Ruby object is the same size: 40 bytes. Objects are not really allocated with m
TL;DR: config.threadsafe! can be removed, but for Rails 4.0 we should just enable it by default. A while back a ticket was filed on the Rails tracker to turn on config.threadsafe! mode by default in production. Unfortunately, this change was met with some resistance. Rather than make resistance to change a negative thing, I would like to make it a positive thing by talking about exactly what confi
Objects in Ruby are 40 bytes. Objects are allocated in to pages (or arenas) that are 2^14 (2 to the 14th power) bytes. Pages are allocated with an aligned malloc where the divisor is the size of a page. The first object is allocated at the first address inside the page that is divisible by 40 (or page_start + (40 - page_start % 40) % 40). This means all Ruby object addresses are divisible by 40, a
I need to know when my cats are pooping so over the weekend I hooked up a motion sensor to my Raspberry PI. This is the code I used to get an interrupt when the motion sensor turns on or off: require 'epoll' def watch pin, on: # Export the pin we want to watch File.binwrite "/sys/class/gpio/export", pin.to_s # It takes time for the pin support files to appear, so retry a few times retries = 0 begi
File.open('somefile.txt', 'wb') do |fh| # Open the file fh.write "hello world" # Do some work with the file end # Close file when block returns ActiveRecord::Base.establish_connection( :adapter => "sqlite", :database => "path/to/dbfile") connection_handle = ActiveRecord::Base.connection def retrieve_connection_pool(klass) pool = @connection_pools[klass.name] return pool if pool return nil if Activ
Update (2023-06-28): Added “I required a file, but I want to know what files were actually loaded” I love puts debugging I am a puts debuggerer. I don’t say this to disparage people that use a Real Debugger. I think Real Debuggers are great, I’ve just never taken the time to learn one well. Every time I try to lean one, I end up not using it for a while and have to re-learn how to use it. Anyway,
Inline Caching Every time you call a method, Ruby must look up the method you want to call before actually calling that method. Trying to figure out what method needs to be called can be a costly operation. So one thing that virtual machine authors try to do is to speed up that process by caching the method lookup. MRI (and most other Ruby virtual machines) store this cache “inline”. Most of us kn
TL;DR: Rack API is poor when you consider streaming response bodies. class FooApplication class ErbPage def to_a head = "the head tag" sleep(2) body = "the body tag" sleep(2) [head, body] end end def call(env) [200, {}, ErbPage.new.to_a] end end class FakeRack def serve(application) status, headers, body = application.call({}) p :status => status p :headers => headers body.each do |string| p strin
Running tests is the worst. Seriously. It takes forever, and by the time they’re all done running, I forgot what I was doing. Some apps take 20 to 30 min to run all the tests, and I just can’t wait that long. What bothers me even more than waiting so long, is that after I make a change to the code, 99% of the tests aren’t even running the code that I changed! Why am I spending time running code th
Ok, so this isn’t really weird stuff, I don’t think. But maybe people don’t know about it so I thought I would post. Hashes dup string keys When you assign a string key to a hash, the hash copies the string and freezes it. Here is an example: >> x = 'string' => "string" >> y = {} => {} >> y[x] = :value => :value >> { x => y.keys.first } => {"string"=>"string"} >> { x.object_id => y.keys.first.obje
I’ve been using RSpec in earnest for the past 6 months now, so I thought it’s time to write a blurrrgh poast comparing RSpec with Minitest. I’ve used Minitest for years, and RSpec only for 6 months, so please keep that in mind when reading! PLEASE REMEMBER, I don’t care what test framework you use, as long as you are testing your code. This is a post just about my experience with these two framewo
TL;DR: OutputBuffer subclasses SafeBuffer which forces us to do runtime checks that are probably unnecessary I made a post about YAGNI methods hurting you where I said I would provide two examples, but then I got tired of writing the article so I just did one example. Here is the other example! The previous example demonstrated a memory leak that was introduced because the “footprint” (the number
TL;DR: Inheriting from Hash will bite you. ¯\_(ツ)_/¯ This is Yet Another Post about preferring composition over inheritance, but I will try to drive it home with Real World Examples™. I’m not saying “don’t use inheritance”, I am saying “use inheritance conservatively, and when it is appropriate” (I know it’s not very controversial). I think I can confidently say “don’t inherit from String, Hash, o
Let’s do something fun! In this post we’ll take a photo using your webcam in Ruby. NOTE: This only works on OS X I haven’t tried making it work on other operating systems. Not that I don’t like other operating systems, I just haven’t made it work. :-) Installing the Gem We’ll use the av_capture gem. It wraps the AVCapture framework on OS X. To install it, just do: $ gem install av_capture Using th
TL;DR: AdequateRecord is a set of patches that adds cache stuff to make ActiveRecord 2x faster I’ve been working on speeding up Active Record, and I’d like to share what I’ve been working on! First, here is a graph: This graph shows the number of times you can call Model.find(id) and Model.find_by_name(name) per second on each stable branch of Rails. Since it is “iterations per second”, a higher v
LIBDIR = Config::CONFIG['libdir'] INCLUDEDIR = Config::CONFIG['includedir'] HEADER_DIRS = [ # First search /opt/local for macports '/opt/local/include', # Then search /usr/local for people that installed from source '/usr/local/include', # Check the ruby install locations INCLUDEDIR, # Finally fall back to /usr '/usr/include', ] LIB_DIRS = [ # First search /opt/local for macports '/opt/local/lib',
TL;DR: depending on your app, using define_method is faster on boot, consumes less memory, and probably doesn’t significantly impact performance. Throughout the Rails code base, I typically see dynamic methods defined using class_eval. What I mean by “dynamic methods” is methods with names or bodies that are calculated at runtime, then defined. For example, something like this: class Foo class_eva
TL;DR This is your periodic reminder to specify dependency versions in your Gemfile I started updating one of our larger projects at work to use edge Rails. This project uses devise, and the Gemfile declares the dependency like this: The latest version of devise correctly declares its dependency on Railties on ~> 3.1: However, Devise version 1.5.3 does not declare a specific dependency on Rails (o
YAML seems to be getting a bad rap lately, and I’m not surprised. YAML was used as the attack vector to execute arbitrary code in a Rails process and was even used to steal secrets from rubygems.org. Let’s try to dissect the attack vector used, and see how YAML fits in to the picture. The Metasploit Exploit First lets cover the most widely known vector. We (the Rails Security Team) have had report
OMG! Happy Thursday! I am trying to be totally enthusiastic, but the truth is that I have a cold, so there will be fewer uppercase letters and exclamation points than usual. Anyway, I want to talk about database connection management in ActiveRecord. I am not too pleased with its current state of affairs. I would like to describe how ActiveRecord connection management works today, how I think it s
TL;DR: respond_to? will return false for protected methods in Ruby 2.0 Let’s check out how protected and private methods behave in Ruby. After that, we’ll look at how Ruby 2.0 changes could possibly break your code (and what to do about it). Method Visibility In Ruby, we have three visibilities: public, protected, and private. Let’s define a class with all three: class Heart def public_method; end
TL;DR Rails 4.0 will allow you to stream arbitrary data at arbitrary intervals with Live Streaming. HAPPY MONDAY EVERYONE! Besides enabling multi-threading by default, one of the things I really wanted for Rails 4.0 is the ability to stream data to the client. I want the ability to treat the response object as an I/O object, and have the data I write immediately available to the client. Essentiall
次のページ
このページを最初にブックマークしてみませんか?
『Tenderlove Making』の新着エントリーを見る
j次のブックマーク
k前のブックマーク
lあとで読む
eコメント一覧を開く
oページを開く