Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions spec/std/benchmark_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ private def h_mean(mean)
end

describe Benchmark::IPS::Entry, "#human_mean" do
it { h_mean(0.01234567890123).should eq(" 0.01 ") }
it { h_mean(0.12345678901234).should eq(" 0.12 ") }
it { h_mean(0.01234567890123).should eq(" 12.35m") }
it { h_mean(0.12345678901234).should eq("123.46m") }

it { h_mean(1.23456789012345).should eq(" 1.23 ") }
it { h_mean(12.3456789012345).should eq(" 12.35 ") }
Expand All @@ -94,7 +94,7 @@ private def h_ips(seconds)
end

describe Benchmark::IPS::Entry, "#human_iteration_time" do
it { h_ips(1234.567_890_123).should eq("1234.57s ") }
it { h_ips(1234.567_890_123).should eq("1,234.57s ") }
it { h_ips(123.456_789_012_3).should eq("123.46s ") }
it { h_ips(12.345_678_901_23).should eq(" 12.35s ") }
it { h_ips(1.234_567_890_123).should eq(" 1.23s ") }
Expand Down
5 changes: 5 additions & 0 deletions spec/std/big/big_int_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,11 @@ describe "BigInt" do
x = 1.to_big_i
x.clone.should eq(x)
end

describe "#humanize_bytes" do
it { BigInt.new("1180591620717411303424").humanize_bytes.should eq("1.0ZiB") }
it { BigInt.new("1208925819614629174706176").humanize_bytes.should eq("1.0YiB") }
end
end

describe "BigInt Math" do
Expand Down
2 changes: 1 addition & 1 deletion spec/std/http/server/handlers/log_handler_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ describe HTTP::LogHandler do
handler = HTTP::LogHandler.new(log_io)
handler.next = ->(ctx : HTTP::Server::Context) { called = true }
handler.call(context)
(log_io.to_s =~ %r(GET / - 200 \(\d.+\))).should be_truthy
log_io.to_s.should match %r(GET / - 200 \(\d+(\.\d+)?[mµn]s\))
called.should be_true
end

Expand Down
111 changes: 111 additions & 0 deletions spec/std/humanize_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
require "spec"

private LENGTH_UNITS = ->(magnitude : Int32, number : Float64) do
case magnitude
when -2, -1 then {-2, " cm"}
when .>=(4)
{3, " km"}
else
magnitude = Number.prefix_index(magnitude)
{magnitude, " #{Number.si_prefix(magnitude)}m"}
end
end

describe Number do
describe "#format" do
it do
1.format.should eq "1"
12.format.should eq "12"
123.format.should eq "123"
1234.format.should eq "1,234"

123.45.format.should eq "123.45"
123.45.format(separator: ',').should eq "123,45"
123.45.format(decimal_places: 3).should eq "123.450"
123.45.format(decimal_places: 3, only_significant: true).should eq "123.45"
123.4567.format(decimal_places: 3).should eq "123.457"

123_456.format.should eq "123,456"
123_456.format(delimiter: '.').should eq "123.456"

123_456.789.format.should eq "123,456.789"
end
end

describe "#humanize" do
it { 0.humanize.should eq "0.0" }
it { 1.humanize.should eq "1.0" }
it { -1.humanize.should eq "-1.0" }
it { 123.humanize.should eq "123" }
it { 123.humanize(2).should eq "120" }
it { 1234.humanize.should eq "1.23k" }
it { 12_345.humanize.should eq "12.3k" }
it { 12_345.humanize(2).should eq "12k" }
it { 1_234_567.humanize.should eq "1.23M" }
it { 1_234_567.humanize(5).should eq "1.2346M" }
it { 12_345_678.humanize(5).should eq "12.346M" }
it { 0.012_345.humanize.should eq "12.3m" }
it { 0.001_234_5.humanize.should eq "1.23m" }
it { 0.000_000_012_345.humanize.should eq "12.3n" }
it { 0.000_000_001.humanize.should eq "1.0n" }
it { 0.000_000_001_235.humanize.should eq "1.24n" }
it { 0.123_456_78.humanize.should eq "123m" }
it { 0.123_456_78.humanize(5).should eq "123.46m" }

it { 1_234.567_890_123.humanize(precision: 2, significant: false).should eq("1.23k") }
it { 123.456_789_012_3.humanize(precision: 2, significant: false).should eq("123.46") }
it { 12.345_678_901_23.humanize(precision: 2, significant: false).should eq("12.35") }
it { 1.234_567_890_123.humanize(precision: 2, significant: false).should eq("1.23") }

it { 0.123_456_789_012.humanize(precision: 2, significant: false).should eq("123.46m") }
it { 0.012_345_678_901.humanize(precision: 2, significant: false).should eq("12.35m") }
it { 0.001_234_567_890.humanize(precision: 2, significant: false).should eq("1.23m") }

it { 0.000_123_456_789.humanize(precision: 2, significant: false).should eq("123.46µ") }
it { 0.000_012_345_678.humanize(precision: 2, significant: false).should eq("12.35µ") }
it { 0.000_001_234_567.humanize(precision: 2, significant: false).should eq("1.23µ") }

it { 0.000_000_123_456.humanize(precision: 2, significant: false).should eq("123.46n") }
it { 0.000_000_012_345.humanize(precision: 2, significant: false).should eq("12.35n") }
it { 0.000_000_001_234.humanize(precision: 2, significant: false).should eq("1.23n") }
it { 0.000_000_000_123.humanize(precision: 2, significant: false).should eq("123.00p") }

describe "using custom prefixes" do
it { 1_420_000_000.humanize(prefixes: LENGTH_UNITS).should eq "1,420,000 km" }
it { 1_420.humanize(prefixes: LENGTH_UNITS).should eq "1.42 km" }
it { 1.humanize(prefixes: LENGTH_UNITS).should eq "1.0 m" }
it { 0.1.humanize(prefixes: LENGTH_UNITS).should eq "10.0 cm" }
it { 0.01.humanize(prefixes: LENGTH_UNITS).should eq "1.0 cm" }
it { 0.001.humanize(prefixes: LENGTH_UNITS).should eq "1.0 mm" }
it { 0.000_01.humanize(prefixes: LENGTH_UNITS).should eq "10.0 µm" }
it { 0.000_000_001.humanize(prefixes: LENGTH_UNITS).should eq "1.0 nm" }
end
end
end

describe Int do
describe "#humanize_bytes" do
# default IEC
it { 1024.humanize_bytes.should eq "1.0kiB" }

it { 0.humanize_bytes(format: Int::BinaryPrefixFormat::JEDEC).should eq "0B" }
it { 1.humanize_bytes(format: Int::BinaryPrefixFormat::JEDEC).should eq "1B" }
it { 1000.humanize_bytes(format: Int::BinaryPrefixFormat::JEDEC).should eq "1000B" }
it { 1014.humanize_bytes(format: Int::BinaryPrefixFormat::JEDEC).should eq "0.99KB" }
it { 1015.humanize_bytes(format: Int::BinaryPrefixFormat::JEDEC).should eq "1.0KB" }
it { 1024.humanize_bytes(format: Int::BinaryPrefixFormat::JEDEC).should eq "1.0KB" }
it { 1025.humanize_bytes(format: Int::BinaryPrefixFormat::JEDEC).should eq "1.01KB" }
it { 2048.humanize_bytes(format: Int::BinaryPrefixFormat::JEDEC).should eq "2.0KB" }

it { 1536.humanize_bytes(format: Int::BinaryPrefixFormat::JEDEC).should eq("1.5KB") }
it { 524288.humanize_bytes(format: Int::BinaryPrefixFormat::JEDEC).should eq("512KB") }
it { 1048576.humanize_bytes(format: Int::BinaryPrefixFormat::JEDEC).should eq("1.0MB") }
it { 1073741824.humanize_bytes(format: Int::BinaryPrefixFormat::JEDEC).should eq("1.0GB") }
it { 1099511627776.humanize_bytes(format: Int::BinaryPrefixFormat::JEDEC).should eq("1.0TB") }
it { 1125899906842624.humanize_bytes(format: Int::BinaryPrefixFormat::JEDEC).should eq("1.0PB") }
it { 1152921504606846976.humanize_bytes(format: Int::BinaryPrefixFormat::JEDEC).should eq("1.0EB") }

it { 1024.humanize_bytes(format: Int::BinaryPrefixFormat::IEC).should eq "1.0kiB" }
it { 1073741824.humanize_bytes(format: Int::BinaryPrefixFormat::IEC).should eq "1.0GiB" }
end
end
43 changes: 8 additions & 35 deletions src/benchmark/ips.cr
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,15 @@ module Benchmark
def report
max_label = ran_items.max_of &.label.size
max_compare = ran_items.max_of &.human_compare.size
max_bytes_per_op = ran_items.max_of &.bytes_per_op.to_s.size
max_bytes_per_op = ran_items.max_of &.bytes_per_op.humanize(base: 1024).size

ran_items.each do |item|
printf "%s %s (%s) (±%5.2f%%) %s B/op %s\n",
printf "%s %s (%s) (±%5.2f%%) %sB/op %s\n",
item.label.rjust(max_label),
item.human_mean,
item.human_iteration_time,
item.relative_stddev,
item.bytes_per_op.to_s.rjust(max_bytes_per_op),
item.bytes_per_op.humanize(base: 1024).rjust(max_bytes_per_op),
item.human_compare.rjust(max_compare)
end
end
Expand Down Expand Up @@ -185,43 +185,16 @@ module Benchmark
end

def human_mean
case Math.log10(mean)
when Float64::MIN..3
digits = mean
suffix = ' '
when 3..6
digits = mean / 1000
suffix = 'k'
when 6..9
digits = mean / 1_000_000
suffix = 'M'
else
digits = mean / 1_000_000_000
suffix = 'G'
end

"#{digits.round(2).to_s.rjust(6)}#{suffix}"
mean.humanize(precision: 2, significant: false, prefixes: Number::SI_PREFIXES_PADDED).rjust(7)
end

def human_iteration_time
iteration_time = 1.0 / mean

case Math.log10(iteration_time)
when 0..Float64::MAX
digits = iteration_time
suffix = "s "
when -3..0
digits = iteration_time * 1000
suffix = "ms"
when -6..-3
digits = iteration_time * 1_000_000
suffix = "µs"
else
digits = iteration_time * 1_000_000_000
suffix = "ns"
end

"#{digits.round(2).to_s.rjust(6)}#{suffix}"
iteration_time.humanize(precision: 2, significant: false) do |magnitude, _|
magnitude = Number.prefix_index(magnitude).clamp(-9..0)
{magnitude, magnitude == 0 ? "s " : "#{Number.si_prefix(magnitude)}s"}
end.rjust(8)
end

def human_compare
Expand Down
8 changes: 1 addition & 7 deletions src/http/server/handlers/log_handler.cr
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,6 @@ class HTTP::LogHandler
minutes = elapsed.total_minutes
return "#{minutes.round(2)}m" if minutes >= 1

seconds = elapsed.total_seconds
return "#{seconds.round(2)}s" if seconds >= 1

millis = elapsed.total_milliseconds
return "#{millis.round(2)}ms" if millis >= 1

"#{(millis * 1000).round(2)}µs"
"#{elapsed.total_seconds.humanize(precision: 2, significant: false)}s"
end
end
Loading