Posts tagged programming

14 Notes

Most software today is very much like an Egyptian pyramid with millions of bricks piled on top of each other, with no structural integrity, but just done by brute force and thousands of slaves.

28 Notes

What distinguished programmers at the top-performing companies wasn’t greater experience or better pay. It was how much privacy, personal workspace and freedom from interruption they enjoyed.

6 Notes

My fear is that It’s only a matter of time before developers find the risks and expenses prohibitive and retreat to the safety of a larger organization. We’ll be going back to square one.

7 Notes

Tangle

Tangle is a JavaScript library for creating reactive documents. Your readers can interactively explore possibilities, play with parameters, and see the document update immediately. Tangle is super-simple and easy to learn.

I often learn best when I’m able to explore concepts through what-if scenarios. Allowing data to be directly manipulated within the web page is a powerful idea.

13 Notes

When you work with the Chaos Monkey, you quickly learn that everything happens for a reason. Except for those things which happen completely randomly. And that’s why, even though it sounds crazy, the best way to avoid failure is to fail constantly.

Notes

If you write interactive software know this: fluidity of motion is more important than accurate rendering, once a scene is static fidelity is paramount.
Guy English makes a good point about interactive application behavior, citing current and past examples: Always prioritize responding to user input fluidly over perfect visual fidelity. Once the user action is over, then make sure everything looks great.

Notes

But the tragedy is that as soon as you frame internal quality as tradable, you’ve lost. People are so used to quality being tradable that even in the best circumstances you’re going to have difficulty overcoming it. Saying that we need to spend less time adding new features to improve quality is just nailing down the lid.

Instead it’s vital to focus on the true value of internal quality - that it’s the enabler to speed. The purpose of internal quality is to go faster. This cuts both ways, of course, it also means you should understand how putting some time into a refactoring is going to help you go faster, otherwise you shouldn’t be doing it.

Martin Fowler, on the Tradable Quality Hypothesis

22 Notes

Speed Up Your Devise-using Unit Tests

This morning I was giving myself a refresher on how to set up RSpec for testing Rails apps that use the Devise authentication framework. I completely skimmed over the first sentence there on my first pass. It reads:

First, be sure to speed up your tests!

I’m glad I didn’t miss it. That page advises users to edit their initializers/devise.rb file and replace the line:

config.stretches = 10

with:

config.stretches = Rails.env.test? ? 1 : 10

The comments in that initializer file explain that configuration setting as follows:

For bcrypt, this is the cost for hashing the password and defaults to 10. If using other encryptors, it sets how many times you want the password re-encrypted.

Interesting. I did know that Devise uses bcrypt by default, but why not use the other existing hash functions like MD5, SHA1, etc.? And why re-encrypt the password many times for these others? Well, Coda Hale answers that quite nicely:

These are all general purpose hash functions, designed to calculate a digest of huge amounts of data in as short a time as possible. This means that they are fantastic for ensuring the integrity of data and utterly rubbish for storing passwords.

Essentially, because those other algorithms are designed to be fast, if the encrypted password data is ever stolen, someone can use brute-force techniques to discover the original passwords very quickly on modern hardware. How quickly, you wonder? Again, Coda Hale:

A modern server can calculate the MD5 hash of about 330MB every second. If your users have passwords which are lowercase, alphanumeric, and 6 characters long, you can try every single possible password of that size in around 40 seconds.

As he points out, that’s without investing in any software or hardware solutions specially designed to quickly chew through massive amounts of parallelizable calculations.

In contrast, bcrypt is ideal for the task of encrypting passwords precisely because it is slow. In fact, it can be configured to be slower! That’s what the config.stretches value is controlling. In bcrypt’s terms, it is setting the work factor of the encryption which determines how computationally expensive computing the hash will be. So what does that mean in practical terms? One last time, Coda Hale:

How much slower is bcrypt than, say, MD5? Depends on the work factor. Using a work factor of 12, bcrypt hashes the password yaaa in about 0.3 seconds on my laptop. MD5, on the other hand, takes less than a microsecond.

So we’re talking about 5 or so orders of magnitude. Instead of cracking a password every 40 seconds, I’d be cracking them every 12 years or so. Your passwords might not need that kind of security and you might need a faster comparison algorithm, but bcrypt allows you to choose your balance of speed and security. Use it.

Since we know that the config.stretches parameter is controlling how long our passwords take to encrypt, it makes sense to dial that value way down while running our tests.

If you are using a test data generation library like Factory Girl or Machinist, chances are that you are generating a significant number of user objects during your tests. For each one that you save to the database, Devise generates an encrypted password. This obviously takes time, and now we know how to minimize that time while we’re testing. Even in my nascent project, it makes a significant difference.

With my 63 RSpec examples and 79 Cucumber scenarios with 505 steps, before making the configuration adjustment, `time rake` produced:

real  0m51.951s
user  0m47.403s
sys   0m4.135s

With the configuration set to use a stretches value of 1 for the test environment, I get:

real  0m40.272s
user  0m34.181s
sys   0m4.140s

This is a great result for a one line change and I expect the aggregate savings to continue to increase as I write more and more tests.

Notes

How to write a competition-winning StarCraft AI

A fascinating article describing the principles, strategies, and algorithms used by the Berkeley Overmind team to win the AIIDE 2010 StarCraft competition. Some highlights:

  • Potential fields for unit control
  • Reinforcement learning for tuning
  • Threat-aware A* path planning
  • Effectively using unit types that require a high degree of micromanagement (tough for a human, easy for an AI)

Notes

The second lesson I learnt was that I wanted to work with people like Gary, willing to help the whole team, rather than hunting for individual glory. I’ve since worked with a lot of ‘rock star’ programmers, and while they always look good to management, they hate sharing information or credit and end up hampering projects no matter how smart they are as individuals. Gary used his massive brain to help make us all more effective instead, and I’ve always tried to live up to his example.