I have a confession to make. I'm terrible at doing mental math. I was quite good when I was a teenager (as far as I can remember), but it turns out this is a skill that gets weaker if you don't exercise it, much like many others.
I do have some rules of thumb I thought I'd pass along.
OK, let's start with some basic orders of magnitude for base 10.
You see how every 3 orders of magnitude you get another three zeroes. Simple enough.
There's a phrase out there that states that the difference between a billion and a million is about a billion - meaning that a million is not very much in the context of a billion.
Let's do this with orders of magnitudes!
So if you think of this in terms of percentage, each 3 orders of magnitude is one thousand (or 0.1%), 2 orders of magnitude is one hundred (or one percent ratio).
Now you can get a sense of the numbers in terms of orders of magnitude.
Something in the 10^3's range will be 1% of something in the 10^5's range. So one thousand is (unsurprisingly) 1% of one hundred thousand.
Diving with order of magnitudes is pretty straightforward - you're just adding or removing zeroes or orders of magnitude.
One thing to remember when working on this is that in a ratio the unit is going to disappear (as long as you have the same simple unit in numerator and denominator, let's just keep this simple). When actually writing this out on a whiteboard, keeping the units is quite handy.
Some things are better thought of in base ten, and sometimes we'll want to sketch things in base two. Here is a handy set of approximations between them.
|------------------|------------------|
| Base 10 | Base 2 |
|------------------|------------------|
| 10^0 = 1 | 2^0 = 1 |
| 10^1 = 10 | 2^3 = 8 |
| 10^2 = 100 | 2^7 = 128 |
| 10^3 = 1,000 | 2^10 = 1,024 |
| 10^4 = 10,000 | 2^13 = 8,192 |
| 10^5 = 100,000 | 2^17 = 131,072 |
| 10^6 = 1,000,000 | 2^20 = 1,048,576 |
|------------------|------------------|
This comes in handy when calculating the overhead of some value with respect to something else.
This is a classic approximation - how many things can I fit in some memory region?
For example, let's say I have 10MB of memory. I have records that are 500 bytes long that I want to keep around. How many record can I fit?
Let's keep it simple and work in base 10. 10MB is around 10 x 10^6. 500 bytes is half of 1,000 which is 10^3. Let's work on the magnitude first - 10^6 divided by 10^3 is 10^3. Multiplying by 10 for the original factor, that's 10^4. The record is only half of that, so we can multiply the result by two, so about 2 x 10^4 or 20,000 records.
A quick Excel expression for =10*POWER(2,20)/500
show the result as 20,971.52
, so that's pretty close.
I want to carve out space for an index. Each entry is 20 bytes plus some position. How big should the position value be? How big is my index with one index entry per record?
OK, so we had around 21,000 entries. I'm going to need more than 13 bits (which allows me to index around 8,000 records), but doubling from there gives me 16k, then 32k, so 15 bits is enough. A two-byte index will do nicely, and I have a spare bit if needed.
The 20 bytes plus two for the index is 24 bytes. 24 bytes times the 20,000 or so entries is 480,000 bytes just by simple multiplication, so that's roughly how big my index is going to be.
All in all, 10MB for data and a half MB for indexing for around 20k records in this scenario. Not too hard to do with a spreadsheet, but also you can more or less scratch this stuff on a napkin without too much effort after some practice.
Happy approximations!
Tags: perf