Advertisement
Guest User

Untitled

a guest
Mar 21st, 2019
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.17 KB | None | 0 0
  1. require "benchmark"
  2.  
  3. # ==============================================================================
  4. # encoding Int64 -> Array(UInt8)
  5. # ==============================================================================
  6.  
  7. def encode(x : Int64)
  8. x.unsafe_as(StaticArray(UInt8, 8)).reverse!.to_a
  9. end
  10.  
  11. def encode2(x : Int64)
  12. [ (x >> 56).to_u8, (x >> 48).to_u8, (x >> 40).to_u8, (x >> 32).to_u8,
  13. (x >> 24).to_u8, (x >> 16).to_u8, (x >> 8).to_u8, x.to_u8 ]
  14. end
  15.  
  16. puts "encoding Int64"
  17. Benchmark.ips do |x|
  18. x.report("unsafe") { encode(126_i64) }
  19. x.report("bshift") { encode2(126_i64) }
  20. end
  21.  
  22. # ==============================================================================
  23. # encoding Float64 -> Array(UInt8)
  24. # ==============================================================================
  25.  
  26. def encode(x : Float64)
  27. x.unsafe_as(StaticArray(UInt8, 8)).reverse!.to_a
  28. end
  29.  
  30. def encode2(x : Float64)
  31. encode2(x.unsafe_as(Int64))
  32. end
  33.  
  34. puts "encoding Float64"
  35. Benchmark.ips do |x|
  36. x.report("unsafe") { encode(1.0) }
  37. x.report("bshift") { encode2(1.0) }
  38. end
  39.  
  40. # ==============================================================================
  41. # encoding Int64 <- Array(UInt8)
  42. # ==============================================================================
  43.  
  44. def decode(type : Int64.class, x : Array(UInt8), offset : Int = 0)
  45. x[offset..offset+7].reverse!.to_unsafe.as(Pointer(Int64)).value
  46. end
  47.  
  48. def decode2(type : Int64.class, x : Array(UInt8), offset : Int = 0)
  49. y = 0_i64
  50. y |= x[offset + 7].to_i64
  51. y |= x[offset + 6].to_i64 << 8
  52. y |= x[offset + 5].to_i64 << 16
  53. y |= x[offset + 4].to_i64 << 24
  54. y |= x[offset + 3].to_i64 << 32
  55. y |= x[offset + 2].to_i64 << 40
  56. y |= x[offset + 1].to_i64 << 48
  57. y |= x[offset ].to_i64 << 56
  58. end
  59.  
  60. puts "decoding Int64"
  61. Benchmark.ips do |x|
  62. x.report("unsafe") { decode(Int64, [0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 1_u8]) }
  63. x.report("bshift") { decode2(Int64, [0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 1_u8]) }
  64. end
  65.  
  66. # ==============================================================================
  67. # encoding Float64 <- Array(UInt8)
  68. # ==============================================================================
  69.  
  70. def decode(type : Float64.class, x : Array(UInt8), offset : Int = 0)
  71. x[offset..offset+7].reverse!.to_unsafe.as(Pointer(Float64)).value
  72. end
  73.  
  74. def decode2(type : Float64.class, x : Array(UInt8), offset : Int = 0)
  75. decode2(Int64, x, offset).unsafe_as(Float64)
  76. end
  77.  
  78. puts "decoding Float64"
  79. Benchmark.ips do |x|
  80. x.report("unsafe") { decode(Float64, [0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 1_u8]) }
  81. x.report("bshift") { decode2(Float64, [0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 1_u8]) }
  82. end
  83.  
  84. # ==============================================================================
  85. # check
  86. # ==============================================================================
  87.  
  88. raise "not match unsafe encode/decode for Int64" if decode(Int64, encode(1234567890_i64)) != 1234567890_i64
  89. raise "not match bshift encode2/decode2 for Int64" if decode2(Int64, encode2(1234567890_i64)) != 1234567890_i64
  90.  
  91. raise "not match unsafe encode/decode for Float64" if decode(Float64, encode(12345.67890_f64)) != 12345.67890_f64
  92. raise "not match bshift encode2/decode2 for Float64" if decode2(Float64, encode2(12345.67890_f64)) != 12345.67890_f64
  93.  
  94. # ==============================================================================
  95. # the result
  96. # ==============================================================================
  97.  
  98. # $ crystal -v
  99. # Crystal 0.27.2 (2019-02-05)
  100. #
  101. # LLVM: 6.0.1
  102. # Default target: x86_64-pc-linux-gnu
  103.  
  104. # $ crystal run speedtest.cr --release
  105. # encoding Int64
  106. # unsafe 14.52M ( 68.85ns) (± 4.55%) 48 B/op 1.53× slower
  107. # bshift 22.16M ( 45.13ns) (± 7.33%) 48 B/op fastest
  108. # encoding Float64
  109. # unsafe 14.45M ( 69.18ns) (± 6.83%) 48 B/op 1.50× slower
  110. # bshift 21.73M ( 46.02ns) (± 7.21%) 48 B/op fastest
  111. # decoding Int64
  112. # unsafe 9.39M (106.45ns) (± 5.57%) 97 B/op 2.11× slower
  113. # bshift 19.86M ( 50.36ns) (± 6.54%) 48 B/op fastest
  114. # decoding Float64
  115. # unsafe 9.4M (106.41ns) (± 7.18%) 97 B/op 2.08× slower
  116. # bshift 19.57M ( 51.09ns) (± 8.14%) 49 B/op fastest
  117.  
  118. # ==============================================================================
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement