diff --git a/README.md b/README.md index 24d2c03..31cbbd6 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ store = Kiwi::LevelDBStore(leveldb) ### MemcachedStore -MemcachedStore requires you to have [memcached shard](https://github.com/comandeo/crystal-memcached) +MemcachedStore requires you to have [memcached shard](https://github.com/comandeo/crystal-memcached). ```crystal require "memcached" @@ -73,17 +73,18 @@ store = Kiwi::MemcachedStore.new(Memcached::Client.new) The following table shows **operations per second** for every particular store. -| | set | get | delete | -| ---------------- | -------:| -------:| --------:| -| **MemoryStore** | 1707000 | 4715000 | 6778000 | -| **LevelDBStore** | 67000 | 155000 | 66000 | -| **RedisStore** | 41000 | 41000 | 21000 | -| **FileStore** | 6000 | 17000 | 13000 | +| | set | get | get(empty) | delete | +| ------------------ | ------- | ------- | ---------- | -------- | +| **MemoryStore** | 3056000 | 4166000 | 4074000 | 10473000 | +| **LevelDBStore** | 120000 | 193000 | 253000 | 37000 | +| **RedisStore** | 41000 | 42000 | 42000 | 21000 | +| **MemcachedStore** | 38000 | 41000 | 40000 | 21000 | +| **FileStore** | 27000 | 66000 | 73000 | 8000 | Data information: * Key size: 5-100 bytes. * Value size: 10-1000 bytes. -* Number of items: 200,000 +* Number of items: 100,000 Environment information: @@ -106,6 +107,14 @@ make benchmark make test ``` +# Roadmap + +* Support `#[]=`, `#[]` methods +* Write `Why?` section + * Cache use case + * Easy switch to a different store. + ## Contributors -- [greyblake](https://github.com/greyblake) Sergey Potapov - creator, maintainer +- [greyblake](https://github.com/greyblake) Sergey Potapov - creator, maintainer. +- [mauricioabreu](https://github.com/mauricioabreu) Mauricio de Abreu Antunes - thanks for MemcachedStore. diff --git a/benchmark.cr b/benchmark.cr index cbe6c74..6a6ea6d 100644 --- a/benchmark.cr +++ b/benchmark.cr @@ -1,6 +1,6 @@ require "./src/kiwi" -N = 200_000 +N = 100_000 def benchmark(name) start_time = Time.now @@ -26,38 +26,39 @@ def gen_data data end -puts "Initializing stores..." -stores = Array(Kiwi::Store).new -stores << Kiwi::MemoryStore.new -stores << Kiwi::LevelDBStore.new(LevelDB::DB.new("/tmp/kiwi_benchmark_leveldb")) -stores << Kiwi::RedisStore.new(Redis.new) -stores << Kiwi::FileStore.new("/tmp/kiwi_benchmark_file") -# stores << Kiwi::MemcachedStore.new(Memcached::Client.new) - def measure(stores) puts "Genrating data..." data = gen_data + empty_keys = (0..N).map { |i| "empty-key-#{i}" } + result = Hash(String, Hash(String, Int32)).new puts "Starting...\n\n" stores.each do |store| + store.clear puts store.class store_metrics = Hash(String, Int32).new - store_metrics["set"] = benchmark("#set") do + store_metrics["set"] = benchmark("set") do data.each do |key, val| store.set(key, val) end end - store_metrics["get"] = benchmark("#get") do + store_metrics["get"] = benchmark("get") do + data.each do |key, val| + store.get(key) + end + end + + store_metrics["get_empty"] = benchmark("get (empty)") do data.each do |key, val| store.get(key) end end - store_metrics["delete"] = benchmark("#delete") do + store_metrics["delete"] = benchmark("delete") do data.each do |key, val| store.delete(key) end @@ -65,7 +66,7 @@ def measure(stores) store.clear store_name = store.class.to_s.split("::").last - result[store_name] = store_metrics + result["**#{store_name}**"] = store_metrics end result end @@ -74,27 +75,47 @@ def print_table(result) store_col_size = result.keys.map(&.size).max set_col_size = result.values.map { |metrics| metrics["set"].to_s.size }.max get_col_size = result.values.map { |metrics| metrics["get"].to_s.size }.max + get_empty_col_size = "get(empty)".size delete_col_size = result.values.map { |metrics| metrics["delete"].to_s.size }.max + # header - puts "| " + " " * store_col_size + " | " + "set".ljust(set_col_size) + " | " + "get".ljust(get_col_size) + " | " + "delete".ljust(delete_col_size) + " |" - puts "| " + "-" * store_col_size + " | " + "-" * set_col_size + " | " + "-" * get_col_size + " | " + "-" * delete_col_size + " |" + puts "| " + " " * store_col_size + + " | " + "set".ljust(set_col_size) + + " | " + "get".ljust(get_col_size) + + " | " + "get(empty)".ljust(get_empty_col_size) + + " | " + "delete".ljust(delete_col_size) + + " |" + + puts "| " + "-" * store_col_size + + " | " + "-" * set_col_size + + " | " + "-" * get_col_size + + " | " + "-" * get_empty_col_size + + " | " + "-" * delete_col_size + + " |" # rows result.each do |store, metrics| - print "| " - print store.ljust(store_col_size) - print " | " - print metrics["set"].to_s.rjust(set_col_size) - print " | " - print metrics["get"].to_s.rjust(get_col_size) - print " | " - print metrics["delete"].to_s.rjust(delete_col_size) - puts " |" + puts "| " + store.ljust(store_col_size) + + " | " + metrics["set"].to_s.rjust(set_col_size) + + " | " + metrics["get"].to_s.rjust(get_col_size) + + " | " + metrics["get_empty"].to_s.rjust(get_empty_col_size) + + " | " + metrics["delete"].to_s.rjust(delete_col_size) + + " |" end end + puts +puts "Initializing stores..." +stores = Array(Kiwi::Store).new + +stores << Kiwi::MemoryStore.new +stores << Kiwi::LevelDBStore.new(LevelDB::DB.new("/tmp/kiwi_benchmark_leveldb")) +stores << Kiwi::RedisStore.new(Redis.new) +stores << Kiwi::MemcachedStore.new(Memcached::Client.new) +stores << Kiwi::FileStore.new("/tmp/kiwi_benchmark_file") + result = measure(stores) puts "\n" print_table(result)