For comments, additional notes, corrections, etc. contact @cypher or mail me
Piotr Szotkowski – Profiling Ruby 1.9
Get the code:
$ git clone git://gist.github.com/418076.git
Use profile lib to profile Ruby code:
$ time ruby -r profile eueler.rb 1_000 stupid_prime?
profile library uses a lot of performance itself
ruby-prof is better:
$ time ruby-prof euler.rb 1_000 stupid_prime?
Generate HTML report:
$ ruby-prof
ruby-prof still takes up a lot of performance
$ gem install perftools.rb
Wrapper around Google Performance Tools
$ export CPUPROFILE=euler
$ time ruby -r perftools euler.rb 1_000 stupid_prime?
$ pprof.rb --text eueler
$ export CPUPROFILE_FREQUENCY=10000
$ time ruby -r perftools euler.rb 1_000 stupid_prime?
$ pprof.rb --text eueler
$ pprof.rb --pdf euler
Optimize prime sieve
Ruby’s prime? isn’t actually very fast
What if you want to speed up Ruby since there are no faster algorithms?
Use jRuby, MacRuby, Rubinius
Faster Libraries (NArray, ?)
Use Ruby/FFI to call your C/C++ code from Ruby
Use a Bridge:
- C via MRI
- D via RuDy
- Haskell via Hubris
- Java via jRuby
- .NET via IronRuby
- R via Rserve
What about embedding a foreign language?
Yes we can: RubyInline, ?, Hubris
Reading documentation is also very helpful in optimizing
CUDA – Run computations on your graphics card Can use RubyInline to call out to CUDA
Automagic Ruby-to-C translators
Ruby-optimization mailing list
Threads and Processes
DRb and BrB (DRb on EM)
Memprof
Don’t do premature optimization
Patrick Hüsler – Applications with MacRuby
First possibility: MacRuby
Ruby 1.9 made specifically for OS X
Much nicer than Ruby-Cocoa
Access to Cocoa
Only need Xcode and Interface Builder to work with MacRuby
Apple provides tons of documentation
Use ruby to scratch the itches you have about OS X
Example: Distribute Windows (Window manager)
Demo: Raffle
Creating bindings in Interface Builder
Xcode isn’t that great at developing code
Choctop – manages updating your applications
Rocky Bernstein – Rbdbgr, a debugger for Ruby 1.9
http://wiki.github.com/rocky/rbdbgr/cool-things
https://gist.github.com/375046
http://wiki.github.com/rocky/rbdbgr/how-to-install-rbdbgr
https://github.com/rocky/rb-threadframe https://github.com/rocky/rb-trace https://github.com/rocky/rbdbgr
Yehuda Katz – Why Bundler?
Make dependency management as easy as Rails
Rails set the bar high
Merb had a lot of dependencies
pulls in about a quarter of Rubyforge when doing dependency-resolution
Rails 3 has harder dependency management
Naive Rails2-approach didn’t work in Merb, so had to invent their own
once we have something that works on one system it should work on all systems
Rubygems doesn’t fulfill this requirement, updating gems causes issues
Merb: Don’t list dependencies in bootup script
Bundler: dependency resolution done right
Rubygems dependency resolution: “Uninstall gems until everything works” Hope nobody installs a problematic gem
“Bundler requires people to be good gem citizens” – kinda true
Don’t smash everything into load path, like rip
If stuff breaks after using Bundler, then previous setup just magically happened to work
Gems may be in a git repo, or path
New problem: “Pinning”
Bundler: git and paths are special kinds of gems
Build upon existing Rubygem tools & ecosystem to get functionality for free (mostly)
Require .gemspec in git repo, if you e.g. use C extension
Doesn’t have to work around quirks in gems, unlike e.g. rpg
Also contribute back to Rubygems, where it makes sense
Specs for Bundler are close to reality
full coverage
Tests don’t use mocking, look e.g. at real filesystem
Problem: Integrating system gems
People expect this work:
$ gem install rails
$ rails myapp
$ cd rails
$ rails server
0.9 uses system gems if available, installs others to ~/.bundle
Bundler is not just a gem installer
gem list tells you what’s on your system, Bundler tells you what’s in your app
Gemfile.lock creates a snapshot of gems
In Rails, Groups are the equivalent to environments
If Bundler doesn’t do something you expect, assume there is a reason for that
Suckage: gems that look the same, but actually aren’t
Only choice is to guess, if Bundler gets it wrong, people will be angry (“BUNDLER SUCKS OMG”)
Bundler relies on name and version, if they have different code in them it will cause problems
Append name to self-built gems to avoid this problems
Most likely cause of confusion in Bundler today, not much they can do about it
Bundler-installed gems don’t show up in gem list
BUNDLE_*
bundle exec – run ruby binaries that aren’t in PATH
Locking is optional, which adds confusion
Updating individual libs can also cause problems
Changing platforms also sucks
Most people do this (even Rails):
if RUBY_VERSION <= "1.9"
require 'ruby-debug'
end
Also Problem: People develop on MRI, deploy to JRuby
Bundler 1.0:
- Always install to system gems
sudohacks- Implicit locking – anytime you run anything, Bundler does implicit lock
- Smarter install
bundle update– smart update, updates everythingbundle update rails– get new version of just rails- Platform support in Gemfile, e.g. when you switch to JRuby
- no more
bundle exec– not removed, but should be obsolete. Requires change to~/.profile rake install(self-built gems) – still a huge issue, not sure how to solve this
Don’t do this – spread the word!
If you upgrade multiple things at one time – don’t automatically assume it’s a bundler issue if stuff breaks
Better general education
Bundler is more than a gem installer
Marcin Bunsch – Scripting Mac Applications with Ruby
Problem: Synching Things.app TODO list with Webapp from work
Things has an API – AppleScript
Solution: AppScript. High-level, user-friendly Apple event bridge
can be used from e.g. Python, Ruby
Talks directly to Apple Event API
gem install rb-appscript – works out of the box
Matt Neuburg (author of Scripting Mac Applications With Ruby: An AppleScript Alternative): “I find AppScript + Ruby to be linguistically cleaner + more powerful than AppleScript”
Examples:
- Controlling TextEdit
- Take current Track from iTunes, query YouTube API, display first result in Safari in ~10 lines of Ruby
Things.app has an excellent AppleScript API with excellent documentation
Created things-client: Library to access and manipulate Things TODOs
Demo: Importing & synching TODOs from Tadalist
Appscript on SourceForge things-client on GitHub https://gist.github.com/418129
Script Editor: “Open Dictionary” shows dictionary for all Apps on System
José Valim – DSL or NoDSL? – The power is in the middle
DSL or NoDSL – don’t actually have answer, want discussion about it
mail_form – tries to solve the contact form issue
In Rails, you need:
- Controller (20 LOC)
- Model (30 LOC)
- View (30 LOC)
- Mailer (15 LOC)
- View for Mailer (20 LOC)
This is easy, and if you do it the first time, it’s okay
but second & third time get repetitive
mail_form tries to remove the Model, Mailer + Mailer-View
Idea: Create a DSL!
DSL started simple
needed more flexible way to set from, so extended it to take a Proc
But: Don’t want to put all that info into the Proc
Open-Source –> More and more extensions
Issues:
- Lacks simplicity
- Reduces programmer happiness
Epiphany: No DSL!
Mail is very similar to HTTP response, has a body and a few headers
headers are Key-Value, like Ruby Hashes
Replace DSL by a contract: All you need to do is specify this method, and it has to return a hash w/ the headers
Replaced “It provides a nice DSL” with “it relies on a simple contract” in docs
Rack is another example of a contract-based lib: Provide a method called call, which gets one argument, and returns an array w/ 3 elements
Example: Rake vs. Thor: Divides Ruby community
Rake is a DSL
Thor removes the DSL, uses Ruby methods and modules instead of tasks and namespaces
Some people prefer Rake, some people prefer Thor
Example: RSpec vs. Test::Unit
Example: Scaffold Controller vs. restful!
But one needs to do small tweaks for behavior when using restful!
Created a DSL for that
Required a lot of code to support DSL
InheritedResources – simply uses Ruby facilities (super) to do same thing – no DSL necessary
Less code to maintain – more time to focus on more important features
InheritedResources “won” the battle
Example: ORM Callbacks
DSL not necessary for libs – the programmer who uses it already knows Ruby
Yehuda: “DSLs can lead to better performance, since you can consider the whole system – examples before filters, routers. Advantage of doing stuff on class level instead of instance level”
Elliot Crosby-McCullough – Influencing Users – Libertarian Paternalism in the Ruby Community
“nudge” by Thaler & Sunstein: How to make systems easier to use for people, e.g. health care
Key concepts:
- People make bad decisions
- It is impossible to present a choice without affecting the outcome
Can use 2nd point to mitigate 1st point
Example: Windows installer InstallShield
Presents two options of installation method – Typical Install, and Custom Install
Make default choice for most people (Typical Install), but keep choices around (Custom Install)
Hick’s Law: The time taken to make decision is proportional to the number of choices
What does interface design have to do with code?
Programming isn’t about just building, it’s also about tools that solve specific problems
Interface issues & ideas can also applies to classes & modules
Classes are metaphors for real world
we can reverse process: Look at real-world tools, use them to create clear interfaces & classes
Example: Claw hammer: Has one side to extract a nail, another to hammer a nail
Intuitive & easy to use
More complicated tool: M1911 handgun
Still simple interface
One primary public method (trigger)
No confusion about functionality
Clear intent of usage & problem solving approach
We often think about code as analogue to real world objects, but we can reverse that
Code is not written for user, but other devs that use it
Community case studies:
- Rails
- Telegraphs intent quite well
- Produces clean defaults for people who don’t care or know
- Still able to deal with edge cases
- (Missed the downsides of Rails, sorry)
- Haml
- 37signals
- Highly opinionated
- “Convention without configuration”
How can we help users of our code and systems?
Make it easy to figure out what your class does
Read more outside of computing: economics, psychology, car repair…
Lots of analogous problems out there
Tim Lossen – Remodelling a Facebook game
Game(s) similar to Farmville
Frontend in Flash + ActionScript
Backend in Ruby
Backend is a Black Box
First game used PHP + MySQL
Next game: Rails + MySQL
But not as simple as that
Backend needs to be able to handle a lot of requests
Sharding MySQL is one way of handling problem
But tried to avoid sharding, since it’s hard to do
Just use sharding for failover, not scaling
Most requests are write requests
Switched to Redis
Redis has high throughput even with write operations
Redis has persistence
Worst case you loose 1 second of data in case of crash
Redis is low level
Use AR-like interface for Redis: Remodel
Serialize data structures to YAML string in order to store them in Redis
Since game is not yet live, unknown if this solution avoids sharding
Alternative: Node.js
Since backend is black box, you can remodel without changing frontend
Florian Hanke – Building a search engine with Ruby
Problem: Single-field address search
Most people use two-field approach
Single-field approach: Only information is order of the words
Demo
Input: “Peter”
Search engine aks: Are you looking for a person or a company?
Input: “hans peter”
Problem: First name only? First and last name?
Devising a good single field interface is quite complex
But backend is even more complicated – lots of math stuff
First implementation was slow
Speeding up:
- MySQL –> Hashes
- Strings –> Symbols
- Replace Ruby bottleneck (multiple Array intersection) with C code
Example: intersecting a small and a large array
long & short is faster than short & long
Few people actually look at how Ruby works
Look at the source once in a while
Another problem: Garbage Collector
One possible solution: Simply turn GC off
With Unicorn, simply have workers commit suicide after a set of conditions have been met (e.g. hit memory limit)
Much faster than collecting garbage
Karel Minařík – Spoiling the youth with Ruby
Spent last few years teaching programming to humanistic students
At the end they were able to:
- Simple quantitative text analysis
- Code a simple web app
- understand
curl - Where quite enthusiastic about it
In academia there are a couple of Daimonia (gods, holy cows):
- Students should learn C/Java
- Web is for hobbyists
- Project management is for managers
- UML is mightier than Zeus
- etc.
Programming is a specific way of thinking
Why teach programming to non-programmers?
“To use a tool on a computer you need do little more than point and click; to create a tool, you must understand the arcane art of computer programming” – John Maeda
People “believe” in software (e.g. that Google always delivers correct results)
But systems fail
Technology is complex
Ruby as an “ideal” programming language?
“Only two hard things in computer science: Cache invalidation and naming things” – Phil Karlton
“The limits of my language mena the limits of my world” – Wittgenstein
We use Ruby because:
- It’s expressive
- Flexible and dynamic
- etc.
All those reasons are valid for didactic purposes as well.
Not only about Ruby
But Ruby is maybe in best position
If Perl were designed by a linguist, Ruby was designed by a philosopher
Start with the basics:
Basic concept of programming is the algorithm
Algorithms are similar to recipes
Use simple algorithms to explain them, that can be understood by trying them out, or on a whiteboard
Example: Find largest number in a list
C and Java are arcane for beginners
Ruby program very similar to pseudocode description of the algorithm, little noise
This simple example already explains a lot of concepts (I/O, variables, composite data types, iterating, …)
Introduce the concept of a function, and polymorphism
Pick an example, and stick with it, switching context is distracting
Use resources:
- Learn to Program
- Why’s Poignant Guide
If you’re teaching/training, try to learn something you’re really bad at (e.g. playing a musical instrument, drawing, dancing, martial arts), to put you into the student mindset
Web as a Platform:
- Transparent
- simple to understand
- simple and free dev tools
- low barrier of entry
- etc.
All those reasons are valid for didactic purposes as well
Not enough focus on the web (in teaching)
Wiki as an example web app to implement:
- Minimal & well defined feature set
- Well understood problem
- Used on a daily basis by every student
- Featureset can be expanded based on individual skills
use Sinatra for Webapp:
- Exposes HTTP
- Simple to install and run
- Simple to write “Hello, world!”
Use curl to do test requests
The less lines of code, the greater the chance students will understand code
Refactor code to be more OO
Teach real-world processes and tools, e.g. using Pivotal Tracker and GitHub
Explain concepts via these tools
“The difference between theory and practice is bigger in practice than in theory”
Common curriculum for teaching Ruby would be great
Code should be shared on GitHub
Lightning Talks
Patrick Hüsler – ChocTop
New release – 0.12
Build Xcode projects automatically
Package them
Build Disk Images
Ship your app right away
Update feeds automatically
Use Sparkle
Public/Private Keys to cryptographically sign updates
Deploy automatically
Versioning (via rake)
Socky
WebSocket push server for RoR
Example: Chat that works without flash, HTML + JS only
Cucumber Feature Manager
Synching Wiki + Cucumber features
Lot of work
Allow editing of cucumber features in browser
commit to git
deploy stories
Use Cucumber Tags for grouping features/scenarios
Documentation FTW
Introducing a new programmer to company requires a lot of info transfer
Telling same things all the time
Ruby on Rails already has guides
Use same format for company docs
Spree Guides has had the same idea
Invitation to conference in Spain: http://www.conferenciarails.org
José Valim & Yehuda Katz – Muse
DSL to create DSLs
Writing books
Create tool that creates tasks based on book content
Example: Book has example of using a certain gem, tool inserts that gem as dependency
should automatically generate PDFs, test-driven code in book
Develop in HTML, deliver the Book as PDF
Tests are run while the PDF is built
Ensuring the code in the book passes the tests
Tweet
