bench.sh 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. #!/bin/bash
  2. # download the code and all its dependencies
  3. _go_get() {
  4. go get -u \
  5. "github.com/ugorji/go/codec" "github.com/ugorji/go/codec"/codecgen \
  6. github.com/tinylib/msgp/msgp github.com/tinylib/msgp \
  7. github.com/pquerna/ffjson/ffjson github.com/pquerna/ffjson \
  8. github.com/Sereal/Sereal/Go/sereal \
  9. bitbucket.org/bodhisnarkva/cbor/go \
  10. github.com/davecgh/go-xdr/xdr2 \
  11. gopkg.in/mgo.v2/bson \
  12. gopkg.in/vmihailenco/msgpack.v2 \
  13. github.com/json-iterator/go \
  14. go.mongodb.org/mongo-driver/bson \
  15. github.com/mailru/easyjson/...
  16. }
  17. # add generated tag to the top of each file
  18. _prependbt() {
  19. cat > ${2} <<EOF
  20. // +build generated
  21. EOF
  22. cat ${1} >> ${2}
  23. rm -f ${1}
  24. }
  25. # To run the full suite of benchmarks, including executing against the external frameworks
  26. # listed above, you MUST first run code generation for the frameworks that support it.
  27. #
  28. # If you want to run the benchmarks against code generated values.
  29. # Then first generate the code generated values from values_test.go named typed.
  30. # we cannot normally read a _test.go file, so temporarily copy it into a readable file.
  31. _gen() {
  32. local zsfx="_generated_test.go"
  33. # local z=`pwd`
  34. # z=${z%%/src/*}
  35. # Note: ensure you run the codecgen for this codebase
  36. cp values_test.go v.go &&
  37. echo "codecgen ..." &&
  38. codecgen -nx -rt codecgen -t 'codecgen generated' -o values_codecgen${zsfx} -d 19780 v.go &&
  39. echo "msgp ... " &&
  40. msgp -unexported -tests=false -o=m9.go -file=v.go &&
  41. _prependbt m9.go values_msgp${zsfx} &&
  42. echo "easyjson ... " &&
  43. easyjson -all -no_std_marshalers -omit_empty -output_filename e9.go v.go &&
  44. _prependbt e9.go values_easyjson${zsfx} &&
  45. echo "ffjson ... " &&
  46. ffjson -force-regenerate -reset-fields -w f9.go v.go &&
  47. _prependbt f9.go values_ffjson${zsfx} &&
  48. sed -i '' -e 's+ MarshalJSON(+ _MarshalJSON(+g' values_ffjson${zsfx} &&
  49. sed -i '' -e 's+ UnmarshalJSON(+ _UnmarshalJSON(+g' values_ffjson${zsfx} &&
  50. rm -f easyjson-bootstrap*.go ffjson-inception* &&
  51. rm -f v.go &&
  52. echo "... DONE"
  53. }
  54. # run the full suite of tests
  55. #
  56. # Basically, its a sequence of
  57. # go test -tags "alltests x safe codecgen generated" -bench "CodecSuite or AllSuite or XSuite" -benchmem
  58. #
  59. _suite_any() {
  60. local x="$1"
  61. local g="$2"
  62. local b="$3"
  63. shift
  64. shift
  65. shift
  66. local a=( "" "safe" "notfastpath" "notfastpath safe" "codecgen" "codecgen safe")
  67. if [[ "$g" = "g" ]]; then a=( "generated" "generated safe"); fi
  68. for i in "${a[@]}"; do
  69. echo ">>>> bench TAGS: 'alltests $x $i' SUITE: $b"
  70. go test -run Nothing -tags "alltests $x $i" -bench "$b" -benchmem "$@"
  71. done
  72. }
  73. # _suite() {
  74. # local t="alltests x"
  75. # local a=( "" "safe" "notfastpath" "notfastpath safe" "codecgen" "codecgen safe")
  76. # for i in "${a[@]}"
  77. # do
  78. # echo ">>>> bench TAGS: '$t $i' SUITE: BenchmarkCodecXSuite"
  79. # go test -run Nothing -tags "$t $i" -bench BenchmarkCodecXSuite -benchmem "$@"
  80. # done
  81. # }
  82. # _suite_gen() {
  83. # local t="alltests x"
  84. # local b=( "generated" "generated safe")
  85. # for i in "${b[@]}"
  86. # do
  87. # echo ">>>> bench TAGS: '$t $i' SUITE: BenchmarkCodecXGenSuite"
  88. # go test -run Nothing -tags "$t $i" -bench BenchmarkCodecXGenSuite -benchmem "$@"
  89. # done
  90. # }
  91. # _suite_json() {
  92. # local t="alltests x"
  93. # local a=( "" "safe" "notfastpath" "notfastpath safe" "codecgen" "codecgen safe")
  94. # for i in "${a[@]}"
  95. # do
  96. # echo ">>>> bench TAGS: '$t $i' SUITE: BenchmarkCodecQuickAllJsonSuite"
  97. # go test -run Nothing -tags "$t $i" -bench BenchmarkCodecQuickAllJsonSuite -benchmem "$@"
  98. # done
  99. # }
  100. # _suite_very_quick_json() {
  101. # # Quickly get numbers for json, stdjson, jsoniter and json (codecgen)"
  102. # echo ">>>> very quick json bench"
  103. # go test -run Nothing -tags "alltests x" -bench "__(Json|Std_Json|JsonIter)__" -benchmem "$@"
  104. # echo
  105. # go test -run Nothing -tags "alltests codecgen" -bench "__Json____" -benchmem "$@"
  106. # }
  107. _suite_very_quick_json_via_suite() {
  108. # Quickly get numbers for json, stdjson, jsoniter and json (codecgen)"
  109. echo ">>>> very quick json bench"
  110. local prefix="BenchmarkCodecVeryQuickAllJsonSuite/json-all-bd1......../"
  111. go test -run Nothing -tags "alltests x" -bench BenchmarkCodecVeryQuickAllJsonSuite -benchmem "$@" |
  112. sed -e "s+^$prefix++"
  113. echo "---- CODECGEN RESULTS ----"
  114. go test -run Nothing -tags "alltests codecgen" -bench "__Json____" -benchmem "$@"
  115. }
  116. _suite_very_quick_json_non_suite() {
  117. # Quickly get numbers for json, stdjson, jsoniter and json (codecgen)"
  118. echo ">>>> very quick json bench"
  119. for j in "En" "De"; do
  120. echo "---- codecgen ----"
  121. go test -run Nothing -tags "alltests x generated" -bench "__(Json|Easyjson)__.*${j}" -benchmem "$@"
  122. echo "---- no codecgen ----"
  123. go test -run Nothing -tags "alltests x" -bench "__(Json|Std_Json|JsonIter)__.*${j}" -benchmem "$@"
  124. echo
  125. done
  126. }
  127. _suite_very_quick_json_only_profile() {
  128. local a="${1:-Json}"
  129. shift
  130. local b="${1}"
  131. go test -run Nothing -tags "alltests" -bench "__${a}__.*${b}" \
  132. -benchmem -benchtime 4s \
  133. -cpuprofile cpu.out -memprofile mem.out -memprofilerate 1
  134. }
  135. _suite_trim_output() {
  136. grep -v -E "^(goos:|goarch:|pkg:|PASS|ok)"
  137. }
  138. _usage() {
  139. printf "usage: bench.sh -[dcbsgjqp] for \n"
  140. printf "\t-d download\n"
  141. printf "\t-c code-generate\n"
  142. printf "\t-bsgjqp run suite of tests for [codec, codec and x, codec and x (generated), json, json-quick, json-profile]\n"
  143. }
  144. _main() {
  145. if [[ "$1" == "" || "$1" == "-h" || "$1" == "-?" ]]
  146. then
  147. _usage
  148. return 1
  149. fi
  150. local args=()
  151. while getopts "dcbsjqpg" flag
  152. do
  153. case "$flag" in
  154. d|c|b|s|j|q|p|g) args+=( "$flag" ) ;;
  155. *) _usage; return 1 ;;
  156. esac
  157. done
  158. shift "$((OPTIND-1))"
  159. [[ " ${args[*]} " == *"d"* ]] && _go_get "$@"
  160. [[ " ${args[*]} " == *"c"* ]] && _gen "$@"
  161. [[ " ${args[*]} " == *"b"* ]] && _suite_any - - BenchmarkCodecSuite "$@" | _suite_trim_output
  162. [[ " ${args[*]} " == *"s"* ]] && _suite_any x - BenchmarkCodecXSuite "$@" | _suite_trim_output
  163. [[ " ${args[*]} " == *"g"* ]] && _suite_any x g BenchmarkCodecXGenSuite "$@" | _suite_trim_output
  164. [[ " ${args[*]} " == *"j"* ]] && _suite_any x - BenchmarkCodecQuickAllJsonSuite "$@" | _suite_trim_output
  165. [[ " ${args[*]} " == *"q"* ]] && _suite_very_quick_json_non_suite "$@" | _suite_trim_output
  166. [[ " ${args[*]} " == *"p"* ]] && _suite_very_quick_json_only_profile "$@" | _suite_trim_output
  167. true
  168. # shift $((OPTIND-1))
  169. }
  170. if [ "." = `dirname $0` ]
  171. then
  172. _main "$@"
  173. else
  174. echo "bench.sh must be run from the directory it resides in"
  175. _usage
  176. fi