-
-
Save ruiqiliu/179d200b43fcbb694a627360e1cf26eb to your computer and use it in GitHub Desktop.
Latency Numbers Every Programmer Should Know
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Latency Comparison Numbers (~2012) | |
---------------------------------- | |
L1 cache reference 0.5 ns | |
Branch mispredict 5 ns | |
L2 cache reference 7 ns 14x L1 cache | |
Mutex lock/unlock 25 ns | |
Main memory reference 100 ns 20x L2 cache, 200x L1 cache | |
Compress 1K bytes with Zippy 3,000 ns 3 us | |
Send 1K bytes over 1 Gbps network 10,000 ns 10 us | |
Read 4K randomly from SSD* 150,000 ns 150 us ~1GB/sec SSD | |
Read 1 MB sequentially from memory 250,000 ns 250 us | |
Round trip within same datacenter 500,000 ns 500 us | |
Read 1 MB sequentially from SSD* 1,000,000 ns 1,000 us 1 ms ~1GB/sec SSD, 4X memory | |
Disk seek 10,000,000 ns 10,000 us 10 ms 20x datacenter roundtrip | |
Read 1 MB sequentially from disk 20,000,000 ns 20,000 us 20 ms 80x memory, 20X SSD | |
Send packet CA->Netherlands->CA 150,000,000 ns 150,000 us 150 ms | |
Notes | |
----- | |
1 ns = 10^-9 seconds | |
1 us = 10^-6 seconds = 1,000 ns | |
1 ms = 10^-3 seconds = 1,000 us = 1,000,000 ns | |
Credit | |
------ | |
By Jeff Dean: http://research.google.com/people/jeff/ | |
Originally by Peter Norvig: http://norvig.com/21-days.html#answers | |
Contributions | |
------------- | |
'Humanized' comparison: https://gist.github.com/hellerbarde/2843375 | |
Visual comparison chart: http://i.imgur.com/k0t1e.png |
#!/usr/bin/env python
# Number to guess: How many times can we parse
# 64K of JSON in a second?
import json
with open('./setup/protobuf/message.json') as f:
message = f.read()
def f(NUMBER):
for _ in xrange(NUMBER):
json.loads(message)
import sys
f(int(sys.argv[1]))
Answer: 449 100-1000
解析json对象在 1ms级, 使用protoBuff可以提高10倍
#!/usr/bin/env python
# Number to guess: How many times can we
# select a row from an **unindexed** table with
# 10,000,000 rows?
import sqlite3
conn = sqlite3.connect('./unindexed_db.sqlite')
c = conn.cursor()
def f(NUMBER):
query = "select * from my_table where key = %d" % 5
for i in xrange(NUMBER):
c.execute(query)
c.fetchall()
import sys
f(int(sys.argv[1]))
Answer: 1-10
使用不带索引的字段查询1千万记录, 100ms级别
#!/usr/bin/env python
# Number to guess: How many bytes can we md5sum in a second?
import hashlib
CHUNK_SIZE = 10000
s = 'a' * CHUNK_SIZE
def f(NUMBER):
bytes_hashed = 0
h = hashlib.md5()
while bytes_hashed < NUMBER:
h.update(s)
bytes_hashed += CHUNK_SIZE
h.digest()
import sys
f(int(sys.argv[1]))
Answer: 100,000,000 - 10**9
MD5计算是1ns级别
#include <stdlib.h>
#include <stdio.h>
// Number to guess: How big of an array (in bytes)
// can we allocate and fill with 5s in a second?
// The catch: We do it out of order instead of in order.
int main(int argc, char **argv) {
int NUMBER, i;
NUMBER = atoi(argv[1]);
char* array = malloc(NUMBER);
int j = 1;
for (i = 0; i < NUMBER; ++i) {
j = j * 2;
if (j > NUMBER) {
j = j - NUMBER;
}
// array[j] = j; // 没有局部访问性
array[i] = j; // 有空间局部访问性,有效使用缓存
}
printf("%d", array[NUMBER / 7]);
// so that -O2 doesn't optimize out the loop
return 0;
}
Answer:108-109
主存访问是100ns级别,L2缓存是10ns级别,L1缓存是0.5ns级别
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Answer: 10-100
调用命令,创建进程是10ms级别