bench.sh 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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() {
  60. local t="alltests x"
  61. local a=( "" "safe" "notfastpath" "notfastpath safe" "codecgen" "codecgen safe")
  62. for i in "${a[@]}"
  63. do
  64. echo ">>>> bench TAGS: '$t $i' SUITE: BenchmarkCodecXSuite"
  65. go test -run Nothing -tags "$t $i" -bench BenchmarkCodecXSuite -benchmem "$@"
  66. done
  67. }
  68. _suite_gen() {
  69. local t="alltests x"
  70. local b=( "generated" "generated safe")
  71. for i in "${b[@]}"
  72. do
  73. echo ">>>> bench TAGS: '$t $i' SUITE: BenchmarkCodecXGenSuite"
  74. go test -run Nothing -tags "$t $i" -bench BenchmarkCodecXGenSuite -benchmem "$@"
  75. done
  76. }
  77. _suite_json() {
  78. local t="alltests x"
  79. local a=( "" "safe" "notfastpath" "notfastpath safe" "codecgen" "codecgen safe")
  80. for i in "${a[@]}"
  81. do
  82. echo ">>>> bench TAGS: '$t $i' SUITE: BenchmarkCodecQuickAllJsonSuite"
  83. go test -run Nothing -tags "$t $i" -bench BenchmarkCodecQuickAllJsonSuite -benchmem "$@"
  84. done
  85. }
  86. _suite_very_quick_json_only_profile() {
  87. go test -run Nothing -tags "alltests" -bench "__Json____.*${1}" \
  88. -benchmem -benchtime 4s \
  89. -cpuprofile cpu.out -memprofile mem.out -memprofilerate 1
  90. }
  91. _suite_very_quick_json() {
  92. # Quickly get numbers for json, stdjson, jsoniter and json (codecgen)"
  93. echo ">>>> very quick json bench: hanging (middle) results is for codecgen"
  94. local x=2
  95. if [[ "$x" = 1 ]]; then
  96. go test -run Nothing -tags "alltests x" -bench BenchmarkCodecVeryQuickAllJsonSuite -benchmem "$@"
  97. echo
  98. go test -run Nothing -tags "alltests codecgen" -bench "__Json____" -benchmem "$@"
  99. return
  100. fi
  101. for j in "En" "De"; do
  102. go test -run Nothing -tags "alltests x" -bench "__(Json|Std_Json|JsonIter).*${j}" -benchmem "$@"
  103. echo
  104. go test -run Nothing -tags "alltests codecgen" -bench "__Json____.*${j}" -benchmem "$@"
  105. echo
  106. done
  107. }
  108. _suite_very_quick_json_trim_output() {
  109. _suite_very_quick_json | grep -v -E "^(goos:|goarch:|pkg:|PASS|ok)"
  110. }
  111. _usage() {
  112. echo "usage: bench.sh -[dcsjq] for [download, code-generate, suite-of-tests, json-suite, quick-json-suite] respectively"
  113. }
  114. _main() {
  115. if [[ "$1" == "" || "$1" == "-h" || "$1" == "-?" ]]
  116. then
  117. _usage
  118. return 1
  119. fi
  120. local args=()
  121. while getopts "dcsjqp" flag
  122. do
  123. case "$flag" in
  124. d|c|s|j|q|p) args+=( "$flag" ) ;;
  125. *) _usage; return 1 ;;
  126. esac
  127. done
  128. shift "$((OPTIND-1))"
  129. [[ " ${args[*]} " == *"d"* ]] && _go_get "$@"
  130. [[ " ${args[*]} " == *"c"* ]] && _gen "$@"
  131. [[ " ${args[*]} " == *"s"* ]] && _suite "$@" && _suite_gen "$@"
  132. [[ " ${args[*]} " == *"j"* ]] && _suite_json "$@"
  133. [[ " ${args[*]} " == *"q"* ]] && _suite_very_quick_json_trim_output "$@"
  134. [[ " ${args[*]} " == *"p"* ]] && _suite_very_quick_json_only_profile "$@"
  135. # shift $((OPTIND-1))
  136. }
  137. if [ "." = `dirname $0` ]
  138. then
  139. _main "$@"
  140. else
  141. echo "bench.sh must be run from the directory it resides in"
  142. _usage
  143. fi