This repository has been archived by the owner on Oct 2, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: Use an abstraction layer instead of Hash
Instead of using Hash by its own, use now an abstraction, which may allow more flexibility in the future. For now, as the benchmark below shows, Memory has almost the same performance as Hash but it saves a memory (considering it is a new abstraction this is awesome). Benchmark: hash write 59.87M (±11.77%) fastest memory write 59.63M (±12.64%) 1.00× slower hash read 81.25M (±10.24%) fastest memory read 75.94M (±10.16%) 1.07x slower Inspired by: https://github.com/kostya/memory_cache/blob/master/src/memory_cache.cr
- Loading branch information
1 parent
98e4688
commit d6d472a
Showing
5 changed files
with
145 additions
and
16 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
require "../src/bojack/memory" | ||
require "benchmark" | ||
|
||
hash = {} of String => String | ||
memory = BoJack::Memory(String, String).new | ||
|
||
100_000.times do |i| | ||
hash["key#{i}"] = "value#{i}" | ||
memory.write("key#{i}", "value#{i}") | ||
end | ||
|
||
Benchmark.ips do |b| | ||
b.report("hash write") do | ||
hash["foo"] = "bar" | ||
end | ||
b.report("memory write") do | ||
memory.write("foo", "bar") | ||
end | ||
end | ||
|
||
Benchmark.ips do |b| | ||
b.report("hash read") do | ||
hash["foo"]? | ||
end | ||
|
||
b.report("memory read") do | ||
memory.read("foo") | ||
end | ||
end |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
require "../spec_helper" | ||
require "../src/bojack/memory" | ||
|
||
memory = BoJack::Memory(String, String).new | ||
|
||
module Spec | ||
before_each do | ||
memory.write("diane", "nguyen") | ||
memory.write("todd", "chavez") | ||
end | ||
end | ||
|
||
describe BoJack::Memory do | ||
context "when reading" do | ||
context "a valid key" do | ||
it "reads the value from memory" do | ||
memory.read("diane").should eq("nguyen") | ||
end | ||
end | ||
|
||
context "an invalid key" do | ||
it "raises invalid key error" do | ||
expect_raises { | ||
memory.read("invalid") | ||
} | ||
end | ||
end | ||
end | ||
|
||
context "when writing" do | ||
it "writes the key, value on the storage" do | ||
value = memory.write("princess", "carolyn") | ||
|
||
value.should eq("carolyn") | ||
memory.read("princess").should eq("carolyn") | ||
end | ||
end | ||
|
||
context "when deleting" do | ||
context "a valid key" do | ||
it "deletes the key from the memory" do | ||
value = memory.delete("princess") | ||
|
||
value.should eq("carolyn") | ||
expect_raises { | ||
memory.read("princess") | ||
} | ||
end | ||
end | ||
|
||
context "an invalid key" do | ||
it "raises an error" do | ||
expect_raises { | ||
memory.delete("princess") | ||
} | ||
end | ||
end | ||
end | ||
end |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
module BoJack | ||
class Memory(K, V) | ||
struct Entry(V) | ||
getter value | ||
def initialize(@value : V); end | ||
end | ||
|
||
def initialize | ||
@cache = {} of K => Entry(V) | ||
end | ||
|
||
def write(key : K, value : V) : V | ||
@cache[key] = Entry.new(value) | ||
|
||
value | ||
end | ||
|
||
def read(key : K) : V? | ||
if entry = @cache[key]? | ||
entry.value | ||
else | ||
raise "#{key.to_s} is not a valid key" | ||
end | ||
end | ||
|
||
def delete(key : K) : V? | ||
if entry = @cache.delete(key) | ||
entry.value | ||
else | ||
raise "#{key.to_s} is not a valid key" | ||
end | ||
end | ||
|
||
private def read_entry(key : K) : Entry(V)? | ||
if entry = @cache[key]? | ||
entry | ||
end | ||
end | ||
end | ||
end |
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