Browse Source

some performance tests with a 'huge' file

pull/2/head
Sean Copenhaver 11 years ago
parent
commit
145f92b466
  1. 3
      Makefile
  2. 5
      README.md
  3. 16638
      test/fixtures/dracula.txt
  4. 83
      test/performance.exs

3
Makefile

@ -7,6 +7,9 @@ all: tags test check docs
test: test:
mix test mix test
perf:
elixir -pa ebin test/performance.exs
tags: tags:
ctags -R . ctags -R .

5
README.md

@ -3,4 +3,7 @@
Implementing the rope data structure to play around with Elixir some... and to do something kind of computer sciencey again. Implementing the rope data structure to play around with Elixir some... and to do something kind of computer sciencey again.
It will attempt to provide an API similar to the Elixir String module. Currently, concat is constant time but about twice the overhead of plain binary strings.
While slice is WAY more efficient then plain binary strings. About 3 times faster in small files (tested with 2kb) and up to 50 times faster in huge files (tested with 880kb).
Find is just horrible right now, which limits some of the rope's use.

16638
test/fixtures/dracula.txt

File diff suppressed because it is too large

83
test/perf_test.exs → test/performance.exs

@ -1,4 +1,6 @@
defmodule PerfTest do Code.require_file "test_helper.exs", __DIR__
defmodule PerformanceTest do
use ExUnit.Case use ExUnit.Case
defrecord TestCtxt, defrecord TestCtxt,
@ -7,13 +9,6 @@ defmodule PerfTest do
time: 0 time: 0
test "10,000 concats" do
threshold = 30_000 #30 milliseconds
time = build_rope |> build_ctxt |> run(10_000, :concat)
IO.puts "\nROPE: 10,000 concats took #{time} microseconds"
assert time < threshold, "10,000 concats completed in #{time} microseconds, longer then threshold of #{threshold} microseconds"
end
test "rebalancing 100,000 words" do test "rebalancing 100,000 words" do
threshold = 100_000 #100 milliseconds threshold = 100_000 #100 milliseconds
time = build_long_rope |> build_ctxt |> run(1, :rebalance) time = build_long_rope |> build_ctxt |> run(1, :rebalance)
@ -21,29 +16,57 @@ defmodule PerfTest do
assert time < threshold, "rebalancing worst case 100,000 leaf rope completed in #{time} microseconds, longer then threshold of #{threshold} microseconds" assert time < threshold, "rebalancing worst case 100,000 leaf rope completed in #{time} microseconds, longer then threshold of #{threshold} microseconds"
end end
test "1,000 slices on a balanced rope" do test "small rope performance" do
threshold = 175_000 #100 milliseconds threshold = 3_000 #3 milliseconds
time = build_rope |> build_ctxt |> run(1_000, :slice) time = build_rope |> build_ctxt |> run(1_000, :concat)
IO.puts "\nROPE: 1,000 slice took #{time} microseconds" IO.puts "\nSMALL ROPE: 1,000 concats took #{time} microseconds"
assert time < threshold, "1,000 slices on a balanced rope completed in #{time} microseconds, longer then threshold of #{threshold} microseconds" assert time < threshold, "1,000 concats completed in #{time} microseconds, longer then threshold of #{threshold} microseconds"
threshold = 17_000 #100 milliseconds
time = build_rope |> build_ctxt |> run(10, :slice)
IO.puts "\nSMALL ROPE: 10 slice took #{time} microseconds"
assert time < threshold, "10 slices on a balanced rope completed in #{time} microseconds, longer then threshold of #{threshold} microseconds"
threshold = 1_000
time = build_rope |> build_ctxt |> run(10, :find)
IO.puts "\nSMALL ROPE: 10 find took #{time} microseconds"
assert time < threshold, "10 finds on a balanced rope completed in #{time} microseconds, longer then threshold of #{threshold} microseconds"
end end
test "100 finds on a balanced rope" do test "huge rope performance" do
threshold = 1_000 #1/2 second threshold = 3_000 #3 milliseconds
time = build_rope |> build_ctxt |> run(100, :find) time = build_huge_rope |> build_ctxt |> run(1_000, :concat)
IO.puts "\nROPE: 100 find took #{time} microseconds" IO.puts "\nHUGE ROPE: 1,000 concats took #{time} microseconds"
assert time < threshold, "100 finds on a balanced rope completed in #{time} microseconds, longer then threshold of #{threshold} microseconds" assert time < threshold, "1,000 concats completed in #{time} microseconds, longer then threshold of #{threshold} microseconds"
threshold = 40_000 #40 milliseconds
time = build_huge_rope |> build_ctxt |> run(10, :slice)
IO.puts "\nHUGE ROPE: 10 slice took #{time} microseconds"
assert time < threshold, "10 slices on a balanced rope completed in #{time} microseconds, longer then threshold of #{threshold} microseconds"
IO.puts "\nHUGE ROPE: 10 find took nevermind microseconds"
end end
test "string performance" do test "small string performance" do
time = build_text |> build_ctxt |> run(10_000, :concat) time = build_text |> build_ctxt |> run(1_000, :concat)
IO.puts "\nSTRING: 10,000 concats took #{time} microseconds" IO.puts "\nSMALL STRING: 1,000 concats took #{time} microseconds"
time = build_text |> build_ctxt |> run(1_000, :slice) time = build_text |> build_ctxt |> run(10, :slice)
IO.puts "\nSTRING: 1,000 slices took #{time} microseconds" IO.puts "\nSMALL STRING: 10 slices took #{time} microseconds"
time = build_text |> build_ctxt |> run(100, :find) time = build_text |> build_ctxt |> run(10, :find)
IO.puts "\nSTRING: 100 contains? took #{time} microseconds" IO.puts "\nSMALL STRING: 10 contains? took #{time} microseconds"
end
test "huge string performance" do
time = build_huge_text |> build_ctxt |> run(1000, :concat)
IO.puts "\nHUGE STRING: 1,000 concats took #{time} microseconds"
time = build_huge_text |> build_ctxt |> run(10, :slice)
IO.puts "\nHUGE STRING: 10 slices took #{time} microseconds"
time = build_huge_text |> build_ctxt |> run(10, :find)
IO.puts "\nHUGE STRING: 10 contains? took #{time} microseconds"
end end
@ -57,6 +80,12 @@ defmodule PerfTest do
|> Rope.rebalance |> Rope.rebalance
end end
def build_huge_rope do
File.stream!("test/fixtures/dracula.txt")
|> Enum.reduce("", fn(line, rope) -> Rope.concat(rope, line) end)
|> Rope.rebalance
end
def build_long_rope() do def build_long_rope() do
extra = build_extra extra = build_extra
Enum.reduce(1..100_000, "", fn(_count, left) -> Enum.reduce(1..100_000, "", fn(_count, left) ->
@ -72,6 +101,10 @@ defmodule PerfTest do
File.read!("test/fixtures/hello_ground.txt") File.read!("test/fixtures/hello_ground.txt")
end end
def build_huge_text do
File.read!("test/fixtures/dracula.txt")
end
def get_timestamp do def get_timestamp do
{mega,sec,micro} = :erlang.now() {mega,sec,micro} = :erlang.now()
(mega*1000000+sec)*1000000+micro (mega*1000000+sec)*1000000+micro
Loading…
Cancel
Save