{"action":"closed","issue":{"url":"https://api.github.com/repos/elliotchance/c2go/issues/795","repository_url":"https://api.github.com/repos/elliotchance/c2go","labels_url":"https://api.github.com/repos/elliotchance/c2go/issues/795/labels{/name}","comments_url":"https://api.github.com/repos/elliotchance/c2go/issues/795/comments","events_url":"https://api.github.com/repos/elliotchance/c2go/issues/795/events","html_url":"https://github.com/elliotchance/c2go/issues/795","id":358314128,"node_id":"MDU6SXNzdWUzNTgzMTQxMjg=","number":795,"title":"Conversion of bool to int32 Performs Poorly","user":{"login":"jcburley","id":430319,"node_id":"MDQ6VXNlcjQzMDMxOQ==","avatar_url":"https://avatars1.githubusercontent.com/u/430319?v=4","gravatar_id":"","url":"https://api.github.com/users/jcburley","html_url":"https://github.com/jcburley","followers_url":"https://api.github.com/users/jcburley/followers","following_url":"https://api.github.com/users/jcburley/following{/other_user}","gists_url":"https://api.github.com/users/jcburley/gists{/gist_id}","starred_url":"https://api.github.com/users/jcburley/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jcburley/subscriptions","organizations_url":"https://api.github.com/users/jcburley/orgs","repos_url":"https://api.github.com/users/jcburley/repos","events_url":"https://api.github.com/users/jcburley/events{/privacy}","received_events_url":"https://api.github.com/users/jcburley/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":3,"created_at":"2018-09-08T17:35:54Z","updated_at":"2018-09-12T00:56:00Z","closed_at":"2018-09-12T00:56:00Z","author_association":"CONTRIBUTOR","body":"Use of `map[bool]int32{false: 0, true: 1}[bool-expr]` showed up in my profiling as a major consumer of CPU time.\r\n\r\nI suggest using `func(val) int32 { if val { return 1 } else { return 0 } }(bool-expr)` instead.\r\n\r\nConsider the following program:\r\n\r\n```\r\npackage main\r\n\r\nimport \"flag\"\r\nimport \"fmt\"\r\nimport \"math/rand\"\r\nimport \"os\"\r\nimport \"time\"\r\n\r\nvar n_iterations int = 1 * 1000 * 1000\r\nvar hits int\r\nvar imp string\r\n\r\n// Ideal conversion:\r\nfunc f_bool(n int) bool {\r\n\treturn n == 42\r\n}\r\n\r\nfunc f_int(n int) int32 {\r\n\tif f_bool(n) {\r\n\t\treturn 1\r\n\t} else {\r\n\t\treturn 0\r\n\t}\r\n}\r\n\r\n// c2go conversion (current):\r\nfunc f_int_via_map(n int) int32 {\r\n\treturn map[bool]int32{false: 0, true: 1}[n == 42]\r\n}\r\n\r\n// c2go conversion (proposed):\r\nfunc f_int_via_func(n int) int32 {\r\n\treturn func() int32 { if n == 42 { return 1 } else { return 0 } }()\r\n}\r\n\r\nfunc main() {\r\n\tvar f func (int) int32\r\n\tflag.Parse()\r\n\tswitch imp {\r\n\tcase \"bool\":\r\n\t\tf = f_int\r\n\tcase \"int_via_map\":\r\n\t\tf = f_int_via_map\r\n\tcase \"int_via_func\":\r\n\t\tf = f_int_via_func\r\n\tdefault:\r\n\t\tfmt.Fprintf(os.Stderr, \"Invalid implementation `%s'.\\n\", imp)\r\n\t\tos.Exit(1)\r\n\t}\r\n\t\r\n\trandom := rand.New(rand.NewSource(time.Now().UnixNano()))\r\n\tfor i := 0; i < n_iterations; i += 1 {\r\n\t\tif f(random.Intn(100)) != 0 {\r\n\t\t\thits += 1\r\n\t\t}\r\n\t}\r\n\tfmt.Fprintf(os.Stdout, \"imp=%s n_iterations=%d hits=%d\\n\", imp, n_iterations, hits)\r\n}\r\n\r\nfunc init() {\r\n\tflag.StringVar(&imp, \"implementation\", \"bool\", \"Specify implementation to use: 'bool', 'int_via_map', or 'int_via_func'\")\r\n\tflag.IntVar(&n_iterations, \"iterations\", 1 * 1000 * 1000, \"Specify number of iterations to run\")\r\n}\r\n```\r\n\r\nThe runtimes on my Ubuntu 16.04 machine (with an i7-2600; it's about seven years old) suggest the proposed `func` conversion is about as fast as the ideal (direct-to-bool) conversion, while the current conversion (using `map`) is several times slower:\r\n\r\n```\r\ncraig@doe:~/.go/src/github.com/jcburley/cast (master #)$ time ./cast -implementation bool -iterations $((10 * 1000 * 1000))\r\nimp=bool n_iterations=10000000 hits=100002\r\n\r\nreal\t0m0.288s\r\nuser\t0m0.288s\r\nsys\t0m0.000s\r\ncraig@doe:~/.go/src/github.com/jcburley/cast (master #)$ time ./cast -implementation bool -iterations $((10 * 1000 * 1000))\r\nimp=bool n_iterations=10000000 hits=99791\r\n\r\nreal\t0m0.289s\r\nuser\t0m0.288s\r\nsys\t0m0.000s\r\ncraig@doe:~/.go/src/github.com/jcburley/cast (master #)$ time ./cast -implementation int_via_func -iterations $((10 * 1000 * 1000))\r\nimp=int_via_func n_iterations=10000000 hits=100108\r\n\r\nreal\t0m0.295s\r\nuser\t0m0.292s\r\nsys\t0m0.000s\r\ncraig@doe:~/.go/src/github.com/jcburley/cast (master #)$ time ./cast -implementation int_via_func -iterations $((10 * 1000 * 1000))\r\nimp=int_via_func n_iterations=10000000 hits=100309\r\n\r\nreal\t0m0.287s\r\nuser\t0m0.284s\r\nsys\t0m0.000s\r\ncraig@doe:~/.go/src/github.com/jcburley/cast (master #)$ time ./cast -implementation int_via_func -iterations $((10 * 1000 * 1000))\r\nimp=int_via_func n_iterations=10000000 hits=99742\r\n\r\nreal\t0m0.295s\r\nuser\t0m0.292s\r\nsys\t0m0.000s\r\ncraig@doe:~/.go/src/github.com/jcburley/cast (master #)$ time ./cast -implementation int_via_map -iterations $((10 * 1000 * 1000))\r\nimp=int_via_map n_iterations=10000000 hits=100125\r\n\r\nreal\t0m1.366s\r\nuser\t0m1.364s\r\nsys\t0m0.000s\r\ncraig@doe:~/.go/src/github.com/jcburley/cast (master #)$ time ./cast -implementation int_via_map -iterations $((10 * 1000 * 1000))\r\nimp=int_via_map n_iterations=10000000 hits=100485\r\n\r\nreal\t0m1.368s\r\nuser\t0m1.364s\r\nsys\t0m0.004s\r\ncraig@doe:~/.go/src/github.com/jcburley/cast (master #)$ time ./cast -implementation int_via_map -iterations $((10 * 1000 * 1000))\r\nimp=int_via_map n_iterations=10000000 hits=100081\r\n\r\nreal\t0m1.372s\r\nuser\t0m1.364s\r\nsys\t0m0.004s\r\ncraig@doe:~/.go/src/github.com/jcburley/cast (master #)$\r\n```"}}
{"actor":{"display_login":"elliotchance"}}