Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- require "benchmark"
- # ==============================================================================
- # encoding Int64 -> Array(UInt8)
- # ==============================================================================
- def encode(x : Int64)
- x.unsafe_as(StaticArray(UInt8, 8)).reverse!.to_a
- end
- def encode2(x : Int64)
- [ (x >> 56).to_u8, (x >> 48).to_u8, (x >> 40).to_u8, (x >> 32).to_u8,
- (x >> 24).to_u8, (x >> 16).to_u8, (x >> 8).to_u8, x.to_u8 ]
- end
- puts "encoding Int64"
- Benchmark.ips do |x|
- x.report("unsafe") { encode(126_i64) }
- x.report("bshift") { encode2(126_i64) }
- end
- # ==============================================================================
- # encoding Float64 -> Array(UInt8)
- # ==============================================================================
- def encode(x : Float64)
- x.unsafe_as(StaticArray(UInt8, 8)).reverse!.to_a
- end
- def encode2(x : Float64)
- encode2(x.unsafe_as(Int64))
- end
- puts "encoding Float64"
- Benchmark.ips do |x|
- x.report("unsafe") { encode(1.0) }
- x.report("bshift") { encode2(1.0) }
- end
- # ==============================================================================
- # encoding Int64 <- Array(UInt8)
- # ==============================================================================
- def decode(type : Int64.class, x : Array(UInt8), offset : Int = 0)
- x[offset..offset+7].reverse!.to_unsafe.as(Pointer(Int64)).value
- end
- def decode2(type : Int64.class, x : Array(UInt8), offset : Int = 0)
- y = 0_i64
- y |= x[offset + 7].to_i64
- y |= x[offset + 6].to_i64 << 8
- y |= x[offset + 5].to_i64 << 16
- y |= x[offset + 4].to_i64 << 24
- y |= x[offset + 3].to_i64 << 32
- y |= x[offset + 2].to_i64 << 40
- y |= x[offset + 1].to_i64 << 48
- y |= x[offset ].to_i64 << 56
- end
- puts "decoding Int64"
- Benchmark.ips do |x|
- x.report("unsafe") { decode(Int64, [0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 1_u8]) }
- x.report("bshift") { decode2(Int64, [0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 1_u8]) }
- end
- # ==============================================================================
- # encoding Float64 <- Array(UInt8)
- # ==============================================================================
- def decode(type : Float64.class, x : Array(UInt8), offset : Int = 0)
- x[offset..offset+7].reverse!.to_unsafe.as(Pointer(Float64)).value
- end
- def decode2(type : Float64.class, x : Array(UInt8), offset : Int = 0)
- decode2(Int64, x, offset).unsafe_as(Float64)
- end
- puts "decoding Float64"
- Benchmark.ips do |x|
- x.report("unsafe") { decode(Float64, [0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 1_u8]) }
- x.report("bshift") { decode2(Float64, [0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 1_u8]) }
- end
- # ==============================================================================
- # check
- # ==============================================================================
- raise "not match unsafe encode/decode for Int64" if decode(Int64, encode(1234567890_i64)) != 1234567890_i64
- raise "not match bshift encode2/decode2 for Int64" if decode2(Int64, encode2(1234567890_i64)) != 1234567890_i64
- raise "not match unsafe encode/decode for Float64" if decode(Float64, encode(12345.67890_f64)) != 12345.67890_f64
- raise "not match bshift encode2/decode2 for Float64" if decode2(Float64, encode2(12345.67890_f64)) != 12345.67890_f64
- # ==============================================================================
- # the result
- # ==============================================================================
- # $ crystal -v
- # Crystal 0.27.2 (2019-02-05)
- #
- # LLVM: 6.0.1
- # Default target: x86_64-pc-linux-gnu
- # $ crystal run speedtest.cr --release
- # encoding Int64
- # unsafe 14.52M ( 68.85ns) (± 4.55%) 48 B/op 1.53× slower
- # bshift 22.16M ( 45.13ns) (± 7.33%) 48 B/op fastest
- # encoding Float64
- # unsafe 14.45M ( 69.18ns) (± 6.83%) 48 B/op 1.50× slower
- # bshift 21.73M ( 46.02ns) (± 7.21%) 48 B/op fastest
- # decoding Int64
- # unsafe 9.39M (106.45ns) (± 5.57%) 97 B/op 2.11× slower
- # bshift 19.86M ( 50.36ns) (± 6.54%) 48 B/op fastest
- # decoding Float64
- # unsafe 9.4M (106.41ns) (± 7.18%) 97 B/op 2.08× slower
- # bshift 19.57M ( 51.09ns) (± 8.14%) 49 B/op fastest
- # ==============================================================================
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement