{"version":3,"sources":["webpack:///./src/views/Chap34Benchmarks.vue?da1e","webpack:///src/views/Chap34Benchmarks.vue","webpack:///./src/views/Chap34Benchmarks.vue?8d37","webpack:///./src/views/Chap34Benchmarks.vue","webpack:///./src/assets/images/benchmark_results.png","webpack:///./src/assets/images/multiple_benchmark_graph.png","webpack:///./src/assets/images/regex_benchmark_multiple.png","webpack:///./src/assets/images/lin-lin-plot.png","webpack:///./src/assets/images/linear_vs_log_scale.png"],"names":["render","_vm","this","_h","$createElement","_c","_self","staticClass","attrs","_v","directives","name","rawName","pre","staticRenderFns","components","FeedbackInvite","BuyCopyInvite","NewsletterInput","ChapterHeading","ChapterBibliography","TOCChapter","NavBar","BIconLink45deg","Footer","mounted","i","mathElements","length","tagName","window","displayMode","throwOnError","macros","fleqn","created","data","publicPath","metaInfo","title","htmlAttrs","lang","meta","charset","content","property","link","rel","href","component","module","exports"],"mappings":"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","file":"js/chunk-005da1b8.082dfc56.js","sourcesContent":["var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',[_c('NavBar'),_c('div',{staticClass:\"container-fluid\"},[_c('b-row',[_c('TOCChapter',{attrs:{\"chapter-id\":\"Chap34Benchmarks\"}}),_c('b-col'),_c('b-col',{attrs:{\"role\":\"main\",\"md\":\"6\"}},[_c('ChapterHeading',{attrs:{\"chapter-title\":\"Chapter 34: Benchmarks\",\"image-name\":\"benchmark.jpg\",\"image-alt\":\"Benchmarks\"}}),_c('div',{staticClass:\"anchor\",attrs:{\"id\":\"what-will-you-learn-in-this-chapter\"}}),_c('h1',{attrs:{\"data-number\":\"1\"}},[_c('span',{staticClass:\"header-section-number\"},[_vm._v(\"1\")]),_vm._v(\" What will you learn in this chapter? \"),_c('a',{attrs:{\"href\":\"#what-will-you-learn-in-this-chapter\"}},[_c('b-icon-link45deg',{staticClass:\"heading-link-icon\",attrs:{\"font-scale\":\"0.7\"}})],1)]),_c('ul',[_c('li',[_c('p',[_vm._v(\"What is a benchmark?\")])]),_c('li',[_c('p',[_vm._v(\"How to write a benchmark.\")])]),_c('li',[_c('p',[_vm._v(\"How to read the results of a benchmark.\")])])]),_c('div',{staticClass:\"anchor\",attrs:{\"id\":\"technical-concepts-covered\"}}),_c('h1',{attrs:{\"data-number\":\"2\"}},[_c('span',{staticClass:\"header-section-number\"},[_vm._v(\"2\")]),_vm._v(\" Technical concepts covered \"),_c('a',{attrs:{\"href\":\"#technical-concepts-covered\"}},[_c('b-icon-link45deg',{staticClass:\"heading-link-icon\",attrs:{\"font-scale\":\"0.7\"}})],1)]),_c('ul',[_c('li',[_c('p',[_vm._v(\"Benchmark\")])]),_c('li',[_c('p',[_vm._v(\"Solver\")])]),_c('li',[_c('p',[_vm._v(\"Memory allocations (dynamic and static)\")])])]),_c('div',{staticClass:\"anchor\",attrs:{\"id\":\"introduction\"}}),_c('h1',{attrs:{\"data-number\":\"3\"}},[_c('span',{staticClass:\"header-section-number\"},[_vm._v(\"3\")]),_vm._v(\" Introduction \"),_c('a',{attrs:{\"href\":\"#introduction\"}},[_c('b-icon-link45deg',{staticClass:\"heading-link-icon\",attrs:{\"font-scale\":\"0.7\"}})],1)]),_c('p',[_vm._v(\"A problem may have different solutions.\")]),_c('p',[_vm._v(\"Let’s take an example: you have lost your keys, and you want to open the door of your house. This problem has several solutions. You can :\")]),_c('ul',[_c('li',[_c('p',[_vm._v(\"Call somebody from your entourage that has a spare key\")])]),_c('li',[_c('p',[_vm._v(\"Call a locksmith to open your door\")])]),_c('li',[_c('p',[_vm._v(\"Go back to where you were and look for your keys; if not found in 3 hours, use solution 1 or 2.\")])]),_c('li',[_c('p',[_vm._v(\"Break a window and enter your house\")])])]),_c('p',[_vm._v(\"Those solutions will have the same result; your door will be open. But if you are reasonable, you can rank those solutions in terms of cost or time. Solution 2 and 4 will cost you money. Solution 3 (look for your keys) will probably cost you more time. But what if you just forget the keys in your car parked 5 minutes away? Clearly, in that case, solution three will cost you less than expected.\")]),_c('p',[_vm._v(\"By examining all the different possible solutions and test them in your imagination, you are making a benchmark.\")]),_c('div',{staticClass:\"anchor\",attrs:{\"id\":\"what-is-a-benchmark\"}}),_c('BuyCopyInvite'),_c('h1',{attrs:{\"data-number\":\"4\"}},[_c('span',{staticClass:\"header-section-number\"},[_vm._v(\"4\")]),_vm._v(\" What is a benchmark \"),_c('a',{attrs:{\"href\":\"#what-is-a-benchmark\"}},[_c('b-icon-link45deg',{staticClass:\"heading-link-icon\",attrs:{\"font-scale\":\"0.7\"}})],1)]),_c('p',[_vm._v(\"A benchmark is a tool to compare systems and components \"),_c('b-link',{staticClass:\"citation\",attrs:{\"data-cites\":\"institute1990ieee\",\"href\":\"#institute1990ieee\"}},[_vm._v(\"[@institute1990ieee]\")]),_vm._v(\". The objective of designing and running a benchmark is to find the best solving strategy (called solver).\")],1),_c('p',[_vm._v(\"A solver is usually a method.\")]),_c('p',[_vm._v(\"To choose the best solver, a rule has to be defined. During the benchmark, execution statistics are gathered (the computation time, the number of affectations, the number of function calls ...). With the help of those statistics, we can choose a decision rule.\")]),_c('p',[_vm._v(\"There is no such thing as a general rule. Rules might differ depending on your needs; for instance, if you want to select the program with less CPU usage, you have to focus only on these statistics. If you design a program that runs on devices with very small memory available, you might focus on the memory usage statistics to choose the best solver.\")]),_c('div',{staticClass:\"anchor\",attrs:{\"id\":\"how-to-write-a-benchmark\"}}),_c('h1',{attrs:{\"data-number\":\"5\"}},[_c('span',{staticClass:\"header-section-number\"},[_vm._v(\"5\")]),_vm._v(\" How to write a benchmark \"),_c('a',{attrs:{\"href\":\"#how-to-write-a-benchmark\"}},[_c('b-icon-link45deg',{staticClass:\"heading-link-icon\",attrs:{\"font-scale\":\"0.7\"}})],1)]),_c('p',[_vm._v(\"We will compare two algorithms to concatenate strings. The first step is to create the two functions that will implement the two solutions :\")]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"// benchmark/basic/bench.go\\npackage basic\\n\\nimport (\\n \\\"bytes\\\"\\n \\\"strings\\\"\\n)\\n\\nfunc ConcatenateBuffer(first string, second string) string {\\n var buffer bytes.Buffer\\n buffer.WriteString(first)\\n buffer.WriteString(second)\\n return buffer.String()\\n}\\n\\nfunc ConcatenateJoin(first string, second string) string {\\n return strings.Join([]string{first, second}, \\\"\\\")\\n}\")])]),_c('p',[_vm._v(\"Both functions concatenate two strings. They use two different methods. The first function \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"ConcatenateBuffer\")])]),_vm._v(\" will use a buffer (from the \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"buffer\")])]),_vm._v(\" package). The second function is a wrapper of the function \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"Join\")])]),_vm._v(\" from the package \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"strings\")])]),_vm._v(\". We want to know which approach is the best.\")]),_c('p',[_vm._v(\"Benchmarks are living next to the unit tests. A benchmark is a function located in a test file. Its name must begin with \"),_c('strong',[_vm._v(\"Benchmark\")]),_vm._v(\". The benchmark functions have the following signature\")]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"func BenchmarkXXX(b *testing.B) {\\n}\")])]),_c('p',[_vm._v(\"This function takes as parameter a pointer to a type struct \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"testing.B\")])]),_vm._v(\" . This type struct has only one property exported: \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"N\")])]),_vm._v(\". Which represents the number of iterations to run. The benchmark will not just run the function one time but several time to gather reliable data about the execution of the benchmarked function. That’s why benchmark functions always encapsulate this kind of for loop :\")]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"for i := 0; i < b.N; i++ {\\n // execute the function here\\n}\")])]),_c('p',[_vm._v(\"You can see that the loop start at 0 and will stop when \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"b.N\")])]),_vm._v(\" is reached. Do not put a value instead of \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"b.N\")])]),_vm._v(\". The benchmark package will run the benchmark once and then decide if it should continue to run it. The value of \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"N\")])]),_vm._v(\" is adjusted to reach a desirable level of reliability (we will go deep on that later in the chapter). Let’s see our two benchmarks :\")]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"// benchmark/basic/bench_test.go \\n\\nvar result string\\nfunc BenchmarkConcatenateBuffer(b *testing.B) {\\n var s string\\n for i := 0; i < b.N; i++ {\\n s = ConcatenateBuffer(\\\"test2\\\",\\\"test3\\\")\\n }\\n result = s\\n}\\n\\nfunc BenchmarkConcatenateJoin(b *testing.B) {\\n var s string\\n for i := 0; i < b.N; i++ {\\n s = ConcatenateJoin(\\\"test2\\\",\\\"test3\\\")\\n }\\n result = s\\n}\")])]),_c('p',[_vm._v(\"We first create a \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"result\")])]),_vm._v(\" variable. This variable is just here to avoid compiler optimization (a tip given by Dave Cheney in a blog post: https://dave.cheney.net/2013/06/30/how-to-write-benchmarks-in-go). We will save the results of our benchmarks in this variable.\")]),_c('p',[_vm._v(\"Then we define our two benchmark functions \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"BenchmarkConcatenateBuffer\")])]),_vm._v(\" and \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"BenchmarkConcatenateJoin\")])]),_vm._v(\". Note that they have very similar constructions. The concatenation result is stored into a variable \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"s\")])]),_vm._v(\". Then we define a for loop, and inside it, we are executing the function we want to bench.\")]),_c('p',[_vm._v(\"The arguments are fixed; we test the function under the same conditions.\")]),_c('div',{staticClass:\"anchor\",attrs:{\"id\":\"how-to-run-benchmarks\"}}),_c('h1',{attrs:{\"data-number\":\"6\"}},[_c('span',{staticClass:\"header-section-number\"},[_vm._v(\"6\")]),_vm._v(\" How to run benchmarks \"),_c('a',{attrs:{\"href\":\"#how-to-run-benchmarks\"}},[_c('b-icon-link45deg',{staticClass:\"heading-link-icon\",attrs:{\"font-scale\":\"0.7\"}})],1)]),_c('p',[_vm._v(\"To run benchmarks, we use the same go test command :\")]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"$ go test -bench=.\")])]),_c('p',[_vm._v(\"This command will output :\")]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"goos: darwin\\ngoarch: amd64\\npkg: go_book/benchmark\\nBenchmarkConcatenateBuffer-8 20000000 98.9 ns/op\\nBenchmarkConcatenateJoin-8 30000000 56.1 ns/op\\nPASS\\nok go_book/benchmark 3.833s\")])]),_c('p',[_vm._v(\"We will see in the next section how to interpret the test results.\")]),_c('p',[_vm._v(\"The previous command will run all the benchmarks of the package.\")]),_c('div',{staticClass:\"anchor\",attrs:{\"id\":\"run-only-one-benchmark\"}}),_c('h2',{attrs:{\"data-number\":\"6.1\"}},[_c('span',{staticClass:\"header-section-number\"},[_vm._v(\"6.1\")]),_vm._v(\" Run only one benchmark \"),_c('a',{attrs:{\"href\":\"#run-only-one-benchmark\"}},[_c('b-icon-link45deg',{staticClass:\"heading-link-icon\",attrs:{\"font-scale\":\"0.7\"}})],1)]),_c('p',[_vm._v(\"To run only the ConcatenateBuffer benchmark, you can use the following command :\")]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"$ go test -bench ConcatenateBuffer\")])]),_c('p',[_vm._v(\"The previous command is a shorthand for :\")]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"$ go test -test.bench ConcatenateBuffer\")])]),_c('div',{staticClass:\"anchor\",attrs:{\"id\":\"run-with-code-without-cli\"}}),_c('h2',{attrs:{\"data-number\":\"6.2\"}},[_c('span',{staticClass:\"header-section-number\"},[_vm._v(\"6.2\")]),_vm._v(\" Run with code (without CLI) \"),_c('a',{attrs:{\"href\":\"#run-with-code-without-cli\"}},[_c('b-icon-link45deg',{staticClass:\"heading-link-icon\",attrs:{\"font-scale\":\"0.7\"}})],1)]),_c('p',[_vm._v(\"The testing package exposes public methods to run a benchmark. Let’s take an example :\")]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"// benchmark/without-cli/main.go\\npackage main\\n\\nimport (\\n \\\"bytes\\\"\\n \\\"fmt\\\"\\n \\\"testing\\\"\\n)\\n\\nfunc main() {\\n res := testing.Benchmark(BenchmarkConcatenateBuffer)\\n fmt.Printf(\\\"Memory allocations : %d \\\\n\\\", res.MemAllocs)\\n fmt.Printf(\\\"Number of bytes allocated: %d \\\\n\\\", res.Bytes)\\n fmt.Printf(\\\"Number of run: %d \\\\n\\\", res.N)\\n fmt.Printf(\\\"Time taken: %s \\\\n\\\", res.T)\\n}\\n\\n// ..\\nfunc BenchmarkConcatenateBuffer(b *testing.B) {\\n //..\\n}\")])]),_c('p',[_vm._v(\"The function \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"testing.Benchmark\")])]),_vm._v(\" is waiting for a valid benchmark function, ie. a variable of type \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"func(b *testing.B)\")])]),_c('strong',[_vm._v(\".\")]),_vm._v(\" Remember that in Go functions are the first-class citizens and can be passed to other functions.\")]),_c('p',[_vm._v(\"The Benchmark function returns a variable of type BenchmarkResult :\")]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"// standard library\\n// src/testing/benchmark.go (v1.11.4)\\ntype BenchmarkResult struct {\\n N int // The number of iterations.\\n T time.Duration // The total time taken.\\n Bytes int64 // Bytes processed in one iteration.\\n MemAllocs uint64 // The total number of memory allocations.\\n MemBytes uint64 // The total number of bytes allocated.\\n}\")])]),_c('div',{staticClass:\"anchor\",attrs:{\"id\":\"benchmark-flags\"}}),_c('h1',{attrs:{\"data-number\":\"7\"}},[_c('span',{staticClass:\"header-section-number\"},[_vm._v(\"7\")]),_vm._v(\" Benchmark flags \"),_c('a',{attrs:{\"href\":\"#benchmark-flags\"}},[_c('b-icon-link45deg',{staticClass:\"heading-link-icon\",attrs:{\"font-scale\":\"0.7\"}})],1)]),_c('dl',[_c('dt',[_vm._v(\"-cpu\")]),_c('dd',[_c('p',[_vm._v(\"Benchmarks are executed by default with GOMAXPROCS processors. To have a reliable benchmark, I suggest you control this value; it should be equal to the number of processors of the targeted machine.\")])])]),_c('div',{staticClass:\"list\"},[_c('p',[_vm._v(\"You must pass a regular expression to this flag. It will launch the benchmark functions which names match the regular expression.\")])]),_c('p',[_vm._v(\"For instance, the command :\")]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"$ go test -bench .\")])]),_c('p',[_vm._v(\"Will launch \"),_c('strong',[_vm._v(\"all\")]),_vm._v(\" the benchmarks.\")]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"$ go test -bench Join\")])]),_c('p',[_vm._v(\"Will launch all the benchmark functions that contain the string \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"\\\"Join\\\"\")])]),_vm._v(\". In the example \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"BenchmarkConcatenateJoin\")])]),_vm._v(\" will be launched but not \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"BenchmarkConcatenateBuffer\")])])]),_c('dl',[_c('dt',[_vm._v(\"-benchtime\")]),_c('dd',[_c('p',[_vm._v(\"This flag allows you to control your benchmarks’ execution time. You have to pass a duration string (ex: \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"3s\")])]),_vm._v(\"). The system will parse the duration and execute benchmarks for the specified amount of time. It means that you can increase/decrease the time that the benchmark will take\")])])]),_c('p',[_c('u',[_vm._v(\"Example\")]),_vm._v(\" : Let’s run the benchmark named \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"BenchmarkConcatenateJoin\")])]),_vm._v(\" for 5 seconds :\")]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"$ go test -bench BenchmarkConcatenateJoin -benchtime 5s\\ngoos: darwin\\ngoarch: amd64\\npkg: go_book/benchmark\\nBenchmarkConcatenateJoin-8 100000000 56.9 ns/op\\nPASS\\nok go_book/benchmark 5.760s\")])]),_c('div',{staticClass:\"list\"},[_c('p',[_vm._v(\"Will display in the result the memory allocation statistics. This flag is boolean; it’s set to \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"false\")])]),_vm._v(\" by default. Just add it to the command line to activate this feature.\")])]),_c('p',[_vm._v(\"Example: We can run benchmarks with memory statistics with the following command :\")]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"$ go test -bench . -benchmem\\ngoos: darwin\\ngoarch: amd64\\npkg: go_book/benchmark\\nBenchmarkConcatenateBuffer-8 20000000 105 ns/op 128 B/op 2 allocs/op\\nBenchmarkConcatenateJoin-8 30000000 60.2 ns/op 16 B/op 1 allocs/op\\nPASS\\nok go_book/benchmark 4.093s\")])]),_c('p',[_vm._v(\"Note that two additional columns are printed into the benchmark results. In the next section, we will see how to read those stats.\")]),_c('div',{staticClass:\"anchor\",attrs:{\"id\":\"how-to-read-benchmark-results\"}}),_c('BuyCopyInvite'),_c('h1',{attrs:{\"data-number\":\"8\"}},[_c('span',{staticClass:\"header-section-number\"},[_vm._v(\"8\")]),_vm._v(\" How to read benchmark results \"),_c('a',{attrs:{\"href\":\"#how-to-read-benchmark-results\"}},[_c('b-icon-link45deg',{staticClass:\"heading-link-icon\",attrs:{\"font-scale\":\"0.7\"}})],1)]),_c('p',[_vm._v(\"I find that benchmarks results are difficult to read. We will go through each kind of statistic. For each statistic, we will try to give actionable advice...\")]),_c('figure',[_c('b-img',{staticClass:\"img-book\",attrs:{\"src\":require('@/assets/images/benchmark_results.png'),\"alt\":\"Benchmark results output[fig:Benchmark-results-output]\",\"fluid\":\"\",\"thumbnail\":\"\"}}),_c('figcaption',{attrs:{\"aria-hidden\":\"true\"}},[_vm._v(\"Benchmark results output\"),_c('span',{attrs:{\"id\":\"fig:Benchmark-results-output\",\"label\":\"fig:Benchmark-results-output\"}},[_vm._v(\"[fig:Benchmark-results-output]\")])])],1),_c('p',[_vm._v(\"In the figure \"),_c('a',{attrs:{\"href\":\"#fig:Benchmark-results-output\",\"data-reference-type\":\"ref\",\"data-reference\":\"fig:Benchmark-results-output\"}},[_vm._v(\"1\")]),_vm._v(\" you can see the standard output of the following command :\")]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"$ go test -bench . -benchmem\")])]),_c('p',[_vm._v(\"Here we are running all the benchmarks of the current packages with memory statistics. The benchmark result contains the following statistics :\")]),_c('ul',[_c('li',[_c('p',[_vm._v(\"The first elements to print in the benchmark result are the two \"),_c('strong',[_vm._v(\"Go env variables\")]),_vm._v(\" \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"GOOS\")])]),_vm._v(\" \"),_c('strong',[_vm._v(\"and\")]),_vm._v(\" \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"GOARCH\")])]),_vm._v(\". You know them already, but they are useful to compare benchmark results.\")])]),_c('li',[_c('p',[_c('strong',[_vm._v(\"Duration\")]),_vm._v(\" : This is the total time taken to execute the benchmarks\")])]),_c('li',[_c('p',[_c('strong',[_vm._v(\"The number of iterations (second column)\")]),_vm._v(\" : Remember that inside every benchmark function, there is a for loop. This number represents the number of time the for loop has run to obtain the statistics. You can increase the number of iterations by using the -benchtime flag to increase the benchmark duration. It’s not the total number of iteration executed by the benchmark.\")])]),_c('li',[_c('p',[_c('strong',[_vm._v(\"Nanoseconds per operation (third column)\")]),_vm._v(\" : it gives you an idea of how fast on \"),_c('strong',[_vm._v(\"average\")]),_vm._v(\" your solver run. In our example the \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"ConcatenateBuffer\")])]),_vm._v(\" function takes on \"),_c('strong',[_vm._v(\"average\")]),_vm._v(\" 55.97 nanoseconds to run. Whereas the \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"ConcatenateJoin\")])]),_vm._v(\" function takes on average 33.63 nanoseconds to run. The fastest function is \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"ConcatenateJoin\")])]),_vm._v(\" in the context of our benchmark.\")])]),_c('li',[_c('dl',[_c('dt',[_c('strong',[_vm._v(\"Number of cores (appended to the name of the benchmark function)\")])]),_c('dd',[_vm._v(\"a benchmark result is relative to the system that runs it. That’s why it’s important to know how many cores are used to run it. In our case, the benchmark is run with eight cores. You can adapt the number of cores to use for running the benchmark by using the flag -cpu. By default, it takes the maximum number of cores available. \")])])]),_c('li',[_c('p',[_c('strong',[_vm._v(\"Number of bytes allocated per operation (fourth column)\")]),_vm._v(\" : This column is present only if you add the flag \"),_c('strong',[_vm._v(\"-benchmem.\")]),_vm._v(\" This will give you an idea about the memory consumption of your solvers. If your focus is to improve memory usage, then you should focus on this statistics.\")])]),_c('li',[_c('p',[_c('strong',[_vm._v(\"Number of allocations per operation (fifth column)\")]),_vm._v(\": the name of this stat speaks for itself. This is the average number of memory allocations per run. In the section \"),_c('a',{attrs:{\"href\":\"#sec:Detect-memory-allocations\",\"data-reference-type\":\"ref\",\"data-reference\":\"sec:Detect-memory-allocations\"}},[_vm._v(\"[sec:Detect-memory-allocations]\")]),_vm._v(\" we will see how to detect memory allocation to improve your code.\")])])]),_c('div',{staticClass:\"anchor\",attrs:{\"id\":\"detect-memory-allocationssecdetect-memory-allocations\"}}),_c('h1',{attrs:{\"data-number\":\"9\"}},[_c('span',{staticClass:\"header-section-number\"},[_vm._v(\"9\")]),_vm._v(\" Detect memory allocations\"),_c('span',{attrs:{\"id\":\"sec:Detect-memory-allocations\",\"label\":\"sec:Detect-memory-allocations\"}},[_vm._v(\"[sec:Detect-memory-allocations]\")]),_vm._v(\" \"),_c('a',{attrs:{\"href\":\"#detect-memory-allocationssecdetect-memory-allocations\"}},[_c('b-icon-link45deg',{staticClass:\"heading-link-icon\",attrs:{\"font-scale\":\"0.7\"}})],1)]),_c('p',[_vm._v(\"Go has a debug mode that allows you to print numerous and highly valuable information about your program’s performance. Memory allocation is an important variable to understand how a program performs. They are roughly two types of memory allocations :\")]),_c('ul',[_c('li',[_c('p',[_c('strong',[_vm._v(\"Static\")]),_vm._v(\" : memory is allocated when the program is started. In C, it happens when you create a global or a static variable. This memory is freed when the program stops. It’s only allocated one time\")])]),_c('li',[_c('p',[_c('strong',[_vm._v(\"Dynamic\")]),_vm._v(\" : In a program, everything is not known when the program is compiled or start. The behavior of the program can vary in function of the user input for instance. Imagine a program that computes highly complex mathematical operations, the memory needed by the program will depend on the input and can vary drastically (making an addition do not require a lot of memory whereas getting the result of !10000 requires a lot more space). This is why programs need to allocate memory dynamically when they run.\")])])]),_c('p',[_vm._v(\"We will focus on dynamic memory allocation. We will use the variable \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"GODEBUG\")])]),_vm._v(\" to output the memory allocations that are done by our two functions.\")]),_c('p',[_vm._v(\"The first thing to do is to create a sample application that will call our two functions :\")]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"package main\\n\\n// inports\\n\\nfunc main() {\\n basic.ConcatenateBuffer(\\\"first\\\",\\\"second\\\")\\n basic.ConcatenateJoin(\\\"first\\\",\\\"second\\\")\\n}\")])]),_c('p',[_vm._v(\"This application will call our two functions (that are part of the package \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"basic\")])]),_vm._v(\" with import path \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"go_book/benchmark/basic\")])]),_c('strong',[_vm._v(\").\")]),_vm._v(\" Then we compile our program :\")]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"$ go build -o allocDetect main.go\")])]),_c('p',[_vm._v(\"Note that the \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"-o\")])]),_vm._v(\" flag is used to give a specific name to our binary. Here we choose to name is \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"allocDetect\")])]),_vm._v(\" you could have named it something else, of course.\")]),_c('p',[_vm._v(\"Then we can run our binary with the \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"GODEBUG\")])]),_vm._v(\" variable set :\")]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"$ GODEBUG=allocfreetrace=1 ./allocDetect &>> trace.log\")])]),_c('p',[_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"GODEBUG\")])]),_vm._v(\" is an environment variable that accepts a list of key-value pairs. Here we tell the go runtime to generate a stack trace for each allocation and free. Then we add \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"\\\"&>> trace.log\\\"\")])]),_vm._v(\" to redirect both the standard output and the standard error to the file trace.log. It will create this file if it does not exist, and if it exists, logs will be appended to it.\")]),_c('p',[_vm._v(\"Inside our trace.log I have 1034 lines of text, consisting of stack traces. How to exploit them? If we refer to the documentation, each program’s memory allocation will generate a stack trace.\")]),_c('p',[_vm._v(\"We can search by hand into this file to see where the allocation append. But we can use the two commands \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"cat\")])]),_vm._v(\" and \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"grep\")])]),_vm._v(\" \"),_c('strong',[_vm._v(\":\")])]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"$ cat trace.log | grep -n /path/to/the/package/basic/bench.go\")])]),_c('p',[_vm._v(\"Here we are first printing the content of the trace.log file with “cat trace.log”, then we are asking \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"grep\")])]),_vm._v(\" to search into this file for the string \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"\\\"/path/to/the/package/basic/bench.go\\\"\")])]),_vm._v(\" (the string \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"\\\"/path/to/the/package/basic/bench.go\\\"\")])]),_vm._v(\" needs to be changed by the path of the package file that you want to analyze)\")]),_c('p',[_vm._v(\"There is a pipe (\"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"|\")])]),_vm._v(\") between the two commands \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"cat trace.log\")])]),_vm._v(\" and \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"grep -n /path/to/the/package/basic/bench.go\")])]),_vm._v(\". The pipe is used to chain commands. The output of the first command is the the input of the second command, the whole command is forming a pipeline.\")]),_c('p',[_vm._v(\"Here is the output :\")]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"988: /path/to/the/package/basic/bench.go:9 +0x31 fp=0xc000044758 sp=0xc000044710 pc=0x1055c81\\n1005: /path/to/the/package/basic/bench.go:12 +0xca fp=0xc000044758 sp=0xc000044710 pc=0x1055d1a\\n1028: /path/to/the/package/basic/bench.go:16 +0x7e fp=0xc00008af58 sp=0xc00008aef0 pc=0x1055dde\")])]),_c('p',[_vm._v(\"The path has been found three times in the trace.log on lines 988, 1005, and 1028 (the line numbers are returned by grep because we added the flag -n). Just next to the path string, you have the line number that caused allocation in /path/to/the/package/basic/bench.go.\")]),_c('p',[_vm._v(\"The next set is to analyze your code to see where memory allocation happens and how you can avoid it. In the ConcatenateBuffer function, line two caused a memory allocation. The creation of the buffer :\")]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"var buffer bytes.Buffer\")])]),_c('p',[_vm._v(\"And the call to the String method :\")]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"buffer.String()\")])]),_c('p',[_vm._v(\"The complete list of debug options is available here: https://golang.org/pkg/runtime/#hdr-Environment_Variables\")]),_c('div',{staticClass:\"anchor\",attrs:{\"id\":\"benchmark-with-variable-input\"}}),_c('h1',{attrs:{\"data-number\":\"10\"}},[_c('span',{staticClass:\"header-section-number\"},[_vm._v(\"10\")]),_vm._v(\" Benchmark with variable input \"),_c('a',{attrs:{\"href\":\"#benchmark-with-variable-input\"}},[_c('b-icon-link45deg',{staticClass:\"heading-link-icon\",attrs:{\"font-scale\":\"0.7\"}})],1)]),_c('p',[_vm._v(\"In the previous sections, we have written benchmarks where the input remains stable. This approach is sufficient for most use cases. But you might need to understand how your function behaves when its arguments change.\")]),_c('p',[_vm._v(\"We will use the method \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"Run\")])]),_vm._v(\" defined in the \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"testing\")])]),_vm._v(\" package. The receiver of this method is a pointer to a \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"testing.B\")])]),_vm._v(\" variable.\")]),_c('p',[_vm._v(\"If we want to go deeper in the analysis, we can test our two functions with variable-length strings. We will use length that are powers of two :\")]),_c('ul',[_c('li',[_c('p',[_vm._v(\"2\")])]),_c('li',[_c('p',[_vm._v(\"16\")])]),_c('li',[_c('p',[_vm._v(\"128\")])]),_c('li',[_c('p',[_vm._v(\"1024\")])]),_c('li',[_c('p',[_vm._v(\"8192\")])]),_c('li',[_c('p',[_vm._v(\"65536\")])]),_c('li',[_c('p',[_vm._v(\"524288\")])]),_c('li',[_c('p',[_vm._v(\"4194304\")])]),_c('li',[_c('p',[_vm._v(\"16777216\")])]),_c('li',[_c('p',[_vm._v(\"134217728\")])])]),_c('p',[_vm._v(\"The first step is to put those integers into a slice named \"),_c('strong',[_vm._v(\"lengths.\")])]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"lengths := []int{2,16,128,1024,8192,65536,524288,4194304,16777216,134217728}\")])]),_c('p',[_vm._v(\"With a for range loop we iterate over those numbers. At each iteration, we create two random strings.\")]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"for _, l := range lengths {\\n first := generateRandomString(l)\\n second := generateRandomString(l)\\n\\n}\")])]),_c('p',[_vm._v(\"Once those two strings are created, we can use them as input for our two benchmarked functions.\")]),_c('p',[_vm._v(\"We will create two sub benchmarks. Sub benchmarks are defined with the help of the Run method. They must be defined into a classical benchmark function. We will name this wrapping function “BenchmarkConcatenation” :\")]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"// benchmark/variable-input/bench_test.go \\n\\nfunc BenchmarkConcatenation(b *testing.B){\\n var s string\\n lengths := []int{2,16,128,1024,8192,65536,524288,4194304,16777216,134217728}\\n for _, l := range lengths {\\n first := generateRandomString(l)\\n second := generateRandomString(l)\\n\\n }\\n}\")])]),_c('p',[_vm._v(\"Inside the for loop, we will call the \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"b.Run\")])]),_vm._v(\" method twice (\"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"b.Run\")])]),_vm._v(\" will create a sub-benchmark). First, we benchmark the \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"ConcatenateJoin\")])]),_vm._v(\" function :\")]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"b.Run(fmt.Sprintf(\\\"ConcatenateJoin-%d\\\",l), func(b *testing.B) {\\n for i := 0; i < b.N; i++ {\\n s = ConcatenateJoin(first, second)\\n }\\n result = s\\n})\")])]),_c('p',[_vm._v(\"And the second time with ConcatenateBuffer :\")]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"b.Run(fmt.Sprintf(\\\"ConcatenateBuffer-%d\\\",l), func(b *testing.B) {\\n for i := 0; i < b.N; i++ {\\n s = ConcatenateBuffer(first, second)\\n }\\n result = s\\n})\")])]),_c('p',[_vm._v(\"Note that the run function takes two arguments :\")]),_c('ul',[_c('li',[_c('p',[_vm._v(\"A \"),_c('strong',[_vm._v(\"name\")]),_vm._v(\", that will be displayed in the benchmark results\")])]),_c('li',[_c('p',[_vm._v(\"A \"),_c('strong',[_vm._v(\"function\")]),_vm._v(\" which represents the sub benchmark. It must take as argument a pointer to a testing.B variable.\")])])]),_c('p',[_vm._v(\"We customize the name of the benchmark. We append at the end of the name the value of \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"l\")])]),_vm._v(\" (which represents the number of characters of the two concatenated strings). This customization is necessary to improve the readability of the results.\")]),_c('p',[_vm._v(\"The second argument is a very classical benchmark function: a for loop that will iterate from \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"1\")])]),_vm._v(\" to \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"b.N\")])]),_vm._v(\" . Inside this, for loop, you finally find the call to the benchmarked function. We save the result of the function to avoid compiler optimization.\")]),_c('p',[_vm._v(\"To run this benchmark, you can use the same command as before :\")]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"$ go test -bench BenchmarkConcatenation -benchmem\\ngoos: darwin\\ngoarch: amd64\\npkg: go_book/benchmark/variableInput\\nBenchmarkConcatenation/ConcatenateJoin-2-8 30000000 51.2 ns/op 4 B/op 1 allocs/op\\nBenchmarkConcatenation/ConcatenateBuffer-2-8 20000000 93.0 ns/op 116 B/op 2 allocs/op\\nBenchmarkConcatenation/ConcatenateJoin-16-8 20000000 62.5 ns/op 32 B/op 1 allocs/op\\nBenchmarkConcatenation/ConcatenateBuffer-16-8 20000000 103 ns/op 144 B/op 2 allocs/op\\n//...\\nok go_book/benchmark/variableInput 33.975s\")])]),_c('p',[_vm._v(\"This is a partial output. I did not copy all the standard output.\")]),_c('p',[_vm._v(\"We can generate a graph from this data to understand the results better. We will redirect the output to a file for further processing :\")]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"$ go test -bench BenchmarkConcatenation -benchmem &>> benchmarkConcatenation.log\")])]),_c('p',[_vm._v(\"Then we can parse the benchmarkConcatenation.log file to generate a table and draw a graph :\")]),_c('figure',[_c('b-img',{staticClass:\"img-book\",attrs:{\"src\":require('@/assets/images/multiple_benchmark_graph.png'),\"alt\":\"Mean execution time (ns/op) in function of string length (log-lin plot)[fig:Mean-execution-time-log]\",\"fluid\":\"\",\"thumbnail\":\"\"}}),_c('figcaption',{attrs:{\"aria-hidden\":\"true\"}},[_vm._v(\"Mean execution time (ns/op) in function of string length (log-lin plot)\"),_c('span',{attrs:{\"id\":\"fig:Mean-execution-time-log\",\"label\":\"fig:Mean-execution-time-log\"}},[_vm._v(\"[fig:Mean-execution-time-log]\")])])],1),_c('div',{staticClass:\"anchor\",attrs:{\"id\":\"logarithmic-scale\"}}),_c('h4',{attrs:{\"data-number\":\"10.0.0.1\"}},[_c('span',{staticClass:\"header-section-number\"},[_vm._v(\"10.0.0.1\")]),_vm._v(\" Logarithmic scale \"),_c('a',{attrs:{\"href\":\"#logarithmic-scale\"}},[_c('b-icon-link45deg',{staticClass:\"heading-link-icon\",attrs:{\"font-scale\":\"0.7\"}})],1)]),_c('p',[_vm._v(\"The figure \"),_c('a',{attrs:{\"href\":\"#fig:Mean-execution-time-log\",\"data-reference-type\":\"ref\",\"data-reference\":\"fig:Mean-execution-time-log\"}},[_vm._v(\"2\")]),_vm._v(\" represented the data on a log-lin plot. A log-lin plot is a graph on which the vertical axis is logarithmic and the horizontal has a logarithmic scale. You might be unfamiliar with that approach (if you know it already, you can skip this section).\")]),_c('p',[_vm._v(\"A logarithmic scale is used when the data range is big. In statistics, the range is the difference between the largest and the smallest value. For the dataset :\")]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"{2,16,128,1024,8192,65536,524288,4194304,16777216,134217728}\")])]),_c('p',[_vm._v(\"the range is \"),_c('span',{staticClass:\"math inline\"},[_vm._v(\"134217728-2=134217726\")]),_vm._v(\". This is big.\")]),_c('p',[_vm._v(\"In that case, it’s recommended to use a logarithmic scale and not a linear scale. Instead of having a scale where one millimeter always represent the same value, with a logarithmic scale, the value of a mark on a scale is equal to the the previous mark multiplied by a constant. This constant can vary, but it’s usually 10. The figure \"),_c('a',{attrs:{\"href\":\"#fig:Linear-scale-vs.log\",\"data-reference-type\":\"ref\",\"data-reference\":\"fig:Linear-scale-vs.log\"}},[_vm._v(\"3\")]),_vm._v(\" shows the difference between the log and the linear scale.\")]),_c('figure',[_c('b-img',{staticClass:\"img-book\",attrs:{\"src\":require('@/assets/images/linear_vs_log_scale.png'),\"alt\":\"Linear scale vs. logarithmic scale[fig:Linear-scale-vs.log]\",\"fluid\":\"\",\"thumbnail\":\"\"}}),_c('figcaption',{attrs:{\"aria-hidden\":\"true\"}},[_vm._v(\"Linear scale vs. logarithmic scale\"),_c('span',{attrs:{\"id\":\"fig:Linear-scale-vs.log\",\"label\":\"fig:Linear-scale-vs.log\"}},[_vm._v(\"[fig:Linear-scale-vs.log]\")])])],1),_c('p',[_vm._v(\"One axis can have a log scale and the other a linear scale. This type of graph is called “log-lin plots”. If both axes have a logarithmic scale, it’s called a log-log plot. Compare the figure \"),_c('a',{attrs:{\"href\":\"#fig:Lin-Lin-plot\",\"data-reference-type\":\"ref\",\"data-reference\":\"fig:Lin-Lin-plot\"}},[_vm._v(\"4\")]),_vm._v(\" and the figure \"),_c('a',{attrs:{\"href\":\"#fig:Mean-execution-time-log\",\"data-reference-type\":\"ref\",\"data-reference\":\"fig:Mean-execution-time-log\"}},[_vm._v(\"2\")]),_vm._v(\". Which plot is better?\")]),_c('figure',[_c('b-img',{staticClass:\"img-book\",attrs:{\"src\":require('@/assets/images/lin-lin-plot.png'),\"alt\":\"Lin-Lin plot[fig:Lin-Lin-plot]\",\"fluid\":\"\",\"thumbnail\":\"\"}}),_c('figcaption',{attrs:{\"aria-hidden\":\"true\"}},[_vm._v(\"Lin-Lin plot\"),_c('span',{attrs:{\"id\":\"fig:Lin-Lin-plot\",\"label\":\"fig:Lin-Lin-plot\"}},[_vm._v(\"[fig:Lin-Lin-plot]\")])])],1),_c('div',{staticClass:\"anchor\",attrs:{\"id\":\"parse-the-benchmark-results\"}}),_c('h4',{attrs:{\"data-number\":\"10.0.0.2\"}},[_c('span',{staticClass:\"header-section-number\"},[_vm._v(\"10.0.0.2\")]),_vm._v(\" Parse the benchmark results \"),_c('a',{attrs:{\"href\":\"#parse-the-benchmark-results\"}},[_c('b-icon-link45deg',{staticClass:\"heading-link-icon\",attrs:{\"font-scale\":\"0.7\"}})],1)]),_c('p',[_vm._v(\"Unfortunately, Go has no internal tool to generate this kind of graph. I had to manually parse the standard benchmark output to get the data. Here is the script I used :\")]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"package main\\n\\nimport (\\n \\\"fmt\\\"\\n \\\"io/ioutil\\\"\\n \\\"regexp\\\"\\n)\\n\\nfunc main() {\\n b, err := ioutil.ReadFile(\\\"/path/to/benchmarkConcatenation.log\\\")\\n if err!= nil {\\n panic(err)\\n }\\n benchmarkResult := string(b)\\n regexBench := regexp.MustCompile(`([a-zA-Z]*)-(\\\\d+)-.* (\\\\d+\\\\.?\\\\d+?)[\\\\t]ns.*[\\\\t](\\\\d+)[\\\\t]B.* (\\\\d+) allocs`)\\n matches := regexBench.FindAllStringSubmatch(benchmarkResult,-1)\\n fmt.Println(\\\"benchmarkedFunction,stringLen,nsPerOp,bytesPerOp,mallocs\\\")\\n for _, m := range matches {\\n fmt.Printf(\\\"%s,%s,%s,%s,%s\\\\n\\\",m[1],m[2],m[3],m[4],m[5])\\n }\\n}\")])]),_c('p',[_vm._v(\"I used the following regular expression with five capturing groups to retrieve the benchmark data :\")]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"`([a-zA-Z]*)-(\\\\d+)-.* (\\\\d+\\\\.?\\\\d+?)[\\\\t]ns.*[\\\\t](\\\\d+)[\\\\t]B.* (\\\\d+) allocs`\")])]),_c('p',[_vm._v(\"On the figure \"),_c('a',{attrs:{\"href\":\"#fig:Regex-capturing-groups\",\"data-reference-type\":\"ref\",\"data-reference\":\"fig:Regex-capturing-groups\"}},[_vm._v(\"5\")]),_vm._v(\" you can see the capturing groups highlighted :\")]),_c('figure',[_c('b-img',{staticClass:\"img-book\",attrs:{\"src\":require('@/assets/images/regex_benchmark_multiple.png'),\"alt\":\"Regex capturing groups highlighted[fig:Regex-capturing-groups]\",\"fluid\":\"\",\"thumbnail\":\"\"}}),_c('figcaption',{attrs:{\"aria-hidden\":\"true\"}},[_vm._v(\"Regex capturing groups highlighted\"),_c('span',{attrs:{\"id\":\"fig:Regex-capturing-groups\",\"label\":\"fig:Regex-capturing-groups\"}},[_vm._v(\"[fig:Regex-capturing-groups]\")])])],1),_c('ul',[_c('li',[_c('p',[_vm._v(\"The first group captures the name of the function benchmarked (which is stored into \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"m[1]\")])]),_vm._v(\")\")])]),_c('li',[_c('p',[_vm._v(\"The second group captures the length of the string (\"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"m[2]\")])]),_vm._v(\")\")])]),_c('li',[_c('p',[_vm._v(\"The third group captures the nanoseconds per operations (\"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"m[3]\")])]),_vm._v(\")\")])]),_c('li',[_c('p',[_vm._v(\"The fourth is the number of bytes in memory per operation (\"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"m[4]\")])]),_vm._v(\")\")])]),_c('li',[_c('p',[_vm._v(\"The final group represent the number of allocations (\"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"m[5]\")])]),_vm._v(\")\")])])]),_c('p',[_vm._v(\"The variable matches is a two dimensional slice of strings : \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"[][]string\")])]),_vm._v(\".\"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"matches[0]\")])]),_vm._v(\" represent the first benchmark and \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"matches[0][1]\")])]),_vm._v(\" the name of the function benchmarked.\")]),_c('div',{staticClass:\"anchor\",attrs:{\"id\":\"bits-of-advice\"}}),_c('h4',{attrs:{\"data-number\":\"10.0.0.3\"}},[_c('span',{staticClass:\"header-section-number\"},[_vm._v(\"10.0.0.3\")]),_vm._v(\" Bits of Advice \"),_c('a',{attrs:{\"href\":\"#bits-of-advice\"}},[_c('b-icon-link45deg',{staticClass:\"heading-link-icon\",attrs:{\"font-scale\":\"0.7\"}})],1)]),_c('ul',[_c('li',[_c('p',[_vm._v(\"Take into consideration the time variable (ns/op) and the memory usage metrics.\")])]),_c('li',[_c('p',[_vm._v(\"Choose the variable (or the mix of variables) that is (are) coherent with your objectives.\")])]),_c('li',[_c('p',[_vm._v(\"Use the logarithmic scale on your graphs when appropriate (large range of data)\")])])]),_c('div',{staticClass:\"anchor\",attrs:{\"id\":\"common-error-b.n-as-argument\"}}),_c('h1',{attrs:{\"data-number\":\"11\"}},[_c('span',{staticClass:\"header-section-number\"},[_vm._v(\"11\")]),_vm._v(\" Common error: b.N as argument \"),_c('a',{attrs:{\"href\":\"#common-error-b.n-as-argument\"}},[_c('b-icon-link45deg',{staticClass:\"heading-link-icon\",attrs:{\"font-scale\":\"0.7\"}})],1)]),_c('p',[_vm._v(\"The time taken by the benchmarked function should not increase when the value of b.N increase. Your function’s input should not depend on the b.N number. Otherwise, your benchmark results will not be significant.\")]),_c('p',[_vm._v(\"Let’s take an example :\")]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"func BenchmarkConcatenateBuffer(b *testing.B) {\\n var s string\\n for i := 0; i < b.N; i++ {\\n s = ConcatenateBuffer(generateRandomString(b.N),generateRandomString(b.N))\\n }\\n result = s\\n}\")])]),_c('p',[_vm._v(\"Here we have modified the input of ConcatenateBuffer. Instead of two fixed string, we use a random string generator named generateRandomString. This function will generate a pseudo-random string with the help of the math/rand package.\")]),_c('p',[_vm._v(\"Let’s see the result of our benchmark :\")]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"BenchmarkConcatenateBuffer-8 30000 138583 ns/op 319600 B/op 8 allocs/op\")])]),_c('p',[_vm._v(\"The final number of operations is only 30.000, and it takes an average of 138,583 nanoseconds per operation.\")]),_c('p',[_vm._v(\"Those results are very different from the one we collected with two fixed strings: 100 nanoseconds per operation.\")]),_c('div',{staticClass:\"anchor\",attrs:{\"id\":\"test-yourself\"}}),_c('BuyCopyInvite'),_c('h1',{attrs:{\"data-number\":\"12\"}},[_c('span',{staticClass:\"header-section-number\"},[_vm._v(\"12\")]),_vm._v(\" Test yourself \"),_c('a',{attrs:{\"href\":\"#test-yourself\"}},[_c('b-icon-link45deg',{staticClass:\"heading-link-icon\",attrs:{\"font-scale\":\"0.7\"}})],1)]),_c('div',{staticClass:\"anchor\",attrs:{\"id\":\"questions\"}}),_c('h2',{attrs:{\"data-number\":\"12.1\"}},[_c('span',{staticClass:\"header-section-number\"},[_vm._v(\"12.1\")]),_vm._v(\" Questions \"),_c('a',{attrs:{\"href\":\"#questions\"}},[_c('b-icon-link45deg',{staticClass:\"heading-link-icon\",attrs:{\"font-scale\":\"0.7\"}})],1)]),_c('ol',{attrs:{\"type\":\"1\"}},[_c('li',[_c('p',[_vm._v(\"What is the standard header of a benchmark function (name and signature)?\")])]),_c('li',[_c('p',[_vm._v(\"Where are benchmark functions located in the source code?\")])]),_c('li',[_c('p',[_vm._v(\"What is the command to use to run a specific benchmark?\")])]),_c('li',[_c('p',[_vm._v(\"Which flag can you use to display memory allocation statistics?\")])]),_c('li',[_c('p',[_vm._v(\"True or False ? The statistics ns/op is the function’s total time to execute during the benchmark run.\")])]),_c('li',[_c('p',[_vm._v(\"How to create a benchmark with variable input?\")])])]),_c('div',{staticClass:\"anchor\",attrs:{\"id\":\"answers\"}}),_c('h2',{attrs:{\"data-number\":\"12.2\"}},[_c('span',{staticClass:\"header-section-number\"},[_vm._v(\"12.2\")]),_vm._v(\" Answers \"),_c('a',{attrs:{\"href\":\"#answers\"}},[_c('b-icon-link45deg',{staticClass:\"heading-link-icon\",attrs:{\"font-scale\":\"0.7\"}})],1)]),_c('ol',{attrs:{\"type\":\"1\"}},[_c('li',[_c('p',[_vm._v(\"What is the standard header of a benchmark function (name and signature)?\")]),_c('ol',{attrs:{\"type\":\"1\"}},[_c('li',[_vm._v(\"func BenchmarkNameHere(b *testing.B)\")])])]),_c('li',[_c('p',[_vm._v(\"Where are benchmark functions located in the source code?\")]),_c('ol',{attrs:{\"type\":\"1\"}},[_c('li',[_vm._v(\"They are placed next to unit tests.\")])])]),_c('li',[_c('p',[_vm._v(\"What is the command to use to run a specific benchmark?\")]),_c('ol',{attrs:{\"type\":\"1\"}},[_c('li',[_c('p',[_vm._v(\"If you have somewhere in your code the benchmark function \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"func BenchmarkConcatenateBuffer(b *testing.B)\")])])])]),_c('li',[_c('p',[_vm._v(\"go test -bench ConcatenateBuffer\")])]),_c('li',[_c('p',[_vm._v(\"the string \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"\\\"ConcatenateBuffer\\\"\")])]),_vm._v(\" is a regular expression\")])])])]),_c('li',[_c('p',[_vm._v(\"Which flag can you use to display memory allocation statistics?\")]),_c('ol',{attrs:{\"type\":\"1\"}},[_c('li',[_vm._v(\"go test -bench . -benchmem\")])])]),_c('li',[_c('p',[_vm._v(\"True or False ? The statistics ns/op is the function’s total time to execute during the benchmark run.\")]),_c('ol',{attrs:{\"type\":\"1\"}},[_c('li',[_c('p',[_vm._v(\"False\")])]),_c('li',[_c('p',[_vm._v(\"This is the \"),_c('strong',[_vm._v(\"average\")]),_vm._v(\" time taken by the function.\")])])])]),_c('li',[_c('p',[_vm._v(\"How to create a benchmark with variable input?\")]),_c('ol',{attrs:{\"type\":\"1\"}},[_c('li',[_vm._v(\"Inside your benchmark function, you can create “sub-benchmarks” with \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"b.Run\")])])])])])]),_c('div',{staticClass:\"anchor\",attrs:{\"id\":\"key-takeaways\"}}),_c('h1',{attrs:{\"data-number\":\"13\"}},[_c('span',{staticClass:\"header-section-number\"},[_vm._v(\"13\")]),_vm._v(\" Key Takeaways \"),_c('a',{attrs:{\"href\":\"#key-takeaways\"}},[_c('b-icon-link45deg',{staticClass:\"heading-link-icon\",attrs:{\"font-scale\":\"0.7\"}})],1)]),_c('ul',[_c('li',[_c('p',[_vm._v(\"The objective of designing and running a benchmark is to find the best solving strategy (called solver).\")])]),_c('li',[_c('p',[_vm._v(\"The term “best” should be adapted for your needs.\")]),_c('ul',[_c('li',[_c('p',[_vm._v(\"Do you want the fastest solver?\")])]),_c('li',[_c('p',[_vm._v(\"Do you want the solver that has the lowest memory footprint?\")])]),_c('li',[_c('p',[_vm._v(\"A combination of both?\")])])])]),_c('li',[_c('p',[_vm._v(\"To create a benchmark, write a function with the following header : \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"func BenchmarkNameHere(b *testing.B)\")])])])]),_c('li',[_c('p',[_vm._v(\"Benchmark functions are placed in unit test files. Here is an example benchmark :\")])])]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"func BenchmarkConcatenateJoin(b *testing.B) {\\n var s string\\n for i := 0; i < b.N; i++ {\\n s = ConcatenateJoin(\\\"test2\\\", \\\"test3\\\")\\n }\\n result = s\\n}\")])]),_c('ul',[_c('li',[_c('p',[_vm._v(\"To run all benchmarks in a module, use the command : \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"$ go test -bench=.\")])])])]),_c('li',[_c('p',[_vm._v(\"To run a specific benchmark, use this command : \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"$ go test -bench ConcatenateBuffer\")])])])]),_c('li',[_c('p',[_vm._v(\"To display memory statistics, add the flag “benchmem” : \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"go test -bench . -benchmem\")])])])]),_c('li',[_c('p',[_vm._v(\"With memory statistics set to ON, you can get the number of bytes allocated per operation and the number of allocations per operation.\")])]),_c('li',[_c('p',[_vm._v(\"The env variable \"),_c('span',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\",\"style\":\"display: inline\"}},[_vm._v(\"GODEBUG\")])]),_vm._v(\" allows you to debug program runtime (listing memory allocations, for instance)\")])]),_c('li',[_c('p',[_vm._v(\"A benchmark function can have sub-benchmarks. This is practical to bench the function against different inputs :\")])])]),_c('pre',{directives:[{name:\"highlightjs\",rawName:\"v-highlightjs\"}]},[_c('code',{pre:true,attrs:{\"class\":\"go\"}},[_vm._v(\"func BenchmarkConcatenation(b *testing.B) {\\n var s string\\n lengths := []int{2, 16, 128, 1024, 8192, 65536, 524288, 4194304, 16777216, 134217728}\\n for _, l := range lengths {\\n first := generateRandomString(l)\\n second := generateRandomString(l)\\n b.Run(fmt.Sprintf(\\\"ConcatenateJoin-%d\\\", l), func(b *testing.B) {\\n for i := 0; i < b.N; i++ {\\n s = ConcatenateJoin(first, second)\\n }\\n result = s\\n })\\n b.Run(fmt.Sprintf(\\\"ConcatenateBuffer-%d\\\", l), func(b *testing.B) {\\n for i := 0; i < b.N; i++ {\\n s = ConcatenateBuffer(first, second)\\n }\\n result = s\\n })\\n }\\n}\")])]),_c('h1',[_vm._v(\"Bibliography\")]),_c('ChapterBibliography',{attrs:{\"chapter-id\":\"Chap34Benchmarks\"}}),_c('b-row',{staticClass:\"ml-1 mr-1 \"},[_c('b-col',{staticClass:\"text-center border mr-1 p-2\"},[_c('router-link',{attrs:{\"to\":{name:'Chap33ApplicationConfiguration'}}},[_c('p',[_c('u',[_c('small',[_vm._v(\"Previous\")])])]),_c('p',[_c('small',[_vm._v(\"Application Configuration\")])])])],1),_c('b-col',{staticClass:\"text-center border p-1 \"},[_c('router-link',{attrs:{\"to\":{name:'Chap35BuildAnHttpClient'}}},[_c('p',[_c('u',[_c('small',[_vm._v(\"Next\")])])]),_c('p',[_c('small',[_vm._v(\"Build an HTTP Client\")])])])],1)],1),_c('b-row',{staticClass:\"mt-1 ml-1 mr-1\"},[_c('b-col',{staticClass:\"text-center border p-1 \"},[_c('b-link',{attrs:{\"to\":{name:'Home'}}},[_vm._v(\"Table of contents\")])],1)],1),_c('FeedbackInvite'),_c('NewsletterInput'),_c('Footer')],1),_c('b-col')],1)],1)],1)}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","\n\n\n\n\n","import mod from \"-!../../node_modules/cache-loader/dist/cjs.js??ref--13-0!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js!../../node_modules/cache-loader/dist/cjs.js??ref--1-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Chap34Benchmarks.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/cache-loader/dist/cjs.js??ref--13-0!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js!../../node_modules/cache-loader/dist/cjs.js??ref--1-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Chap34Benchmarks.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./Chap34Benchmarks.vue?vue&type=template&id=93a818d6&scoped=true&\"\nimport script from \"./Chap34Benchmarks.vue?vue&type=script&lang=js&\"\nexport * from \"./Chap34Benchmarks.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"93a818d6\",\n null\n \n)\n\nexport default component.exports","module.exports = __webpack_public_path__ + \"img/benchmark_results.d02152ba.png\";","module.exports = __webpack_public_path__ + \"img/multiple_benchmark_graph.e048b418.png\";","module.exports = __webpack_public_path__ + \"img/regex_benchmark_multiple.d7dcf827.png\";","module.exports = __webpack_public_path__ + \"img/lin-lin-plot.8567ad48.png\";","module.exports = __webpack_public_path__ + \"img/linear_vs_log_scale.a5e7c71d.png\";"],"sourceRoot":""}