{"action":"created","issue":{"url":"https://api.github.com/repos/manastech/crystal/issues/1632","labels_url":"https://api.github.com/repos/manastech/crystal/issues/1632/labels{/name}","comments_url":"https://api.github.com/repos/manastech/crystal/issues/1632/comments","events_url":"https://api.github.com/repos/manastech/crystal/issues/1632/events","html_url":"https://github.com/manastech/crystal/pull/1632","id":108776132,"number":1632,"title":"refactor(String#split) use the string implementation, even for Chars","user":{"login":"rmosolgo","id":2231765,"avatar_url":"https://avatars.githubusercontent.com/u/2231765?v=3","gravatar_id":"","url":"https://api.github.com/users/rmosolgo","html_url":"https://github.com/rmosolgo","followers_url":"https://api.github.com/users/rmosolgo/followers","following_url":"https://api.github.com/users/rmosolgo/following{/other_user}","gists_url":"https://api.github.com/users/rmosolgo/gists{/gist_id}","starred_url":"https://api.github.com/users/rmosolgo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rmosolgo/subscriptions","organizations_url":"https://api.github.com/users/rmosolgo/orgs","repos_url":"https://api.github.com/users/rmosolgo/repos","events_url":"https://api.github.com/users/rmosolgo/events{/privacy}","received_events_url":"https://api.github.com/users/rmosolgo/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2015-09-29T01:09:16Z","updated_at":"2015-09-29T15:21:03Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/manastech/crystal/pulls/1632","html_url":"https://github.com/manastech/crystal/pull/1632","diff_url":"https://github.com/manastech/crystal/pull/1632.diff","patch_url":"https://github.com/manastech/crystal/pull/1632.patch"},"body":"As I was reading about these methods, I experimented a bit with this one.  I was surprised to find that treating a `Char` like a one-character `String` brought a performance gain.\r\n\r\nOf course, I don't really understand Crystal internals yet so I can't say anything about _why_ ... but, do you want this PR? Or is there something else going on?\r\n\r\nHere's the benchmark:\r\n\r\n```\r\nequire \"benchmark\"\r\n\r\nclass String\r\n  def split_as_string(char : Char, limit)\r\n    split(char.to_s, limit)\r\n  end\r\nend\r\n\r\nshort_string = \"Mississippi\"\r\nlong_string = \"b169af8aff8b146c6a93328f9966fc1558a2e6dd11ca4375ca8dd66265a34364af6cc6805a6cf59b9e07d86c3fa25214f691c76ae5ba7910ff7c1b842cf3521cb5d68f40ee81a21feed0dfefc65b7837cf4fdf682db0608a09584a96cb30ed3c602adc6bee9c775c9dd051bdad64d41d55ad480daee48ff44471778ab868379f077ea12e3cb29aa0cd7446e5a0b31bed3ecf3ef431de0386db7086a0597c714e4f258691a587c7b969116b450d61c8152f8e84df0bb677cff7ac33e45837e5453db4658d1f22641321ea9bdca1873cf3fbad49026b9923bc270e228a413517db1cba135e7f64757a0e73a1384916ecaf83ab4600357f22ce174253e7be17fa12a4632941879fbe0de6744cb4ad6c6d673419a0f6f95b88598c7395648ec5e4161fe6bc0e1b1c8479ed5f8cb6cf8ca0739595cccac06f8756a86e6e6dce1190bbff4a1b14790a8b7e7f966182b539918d06475b36da278d3c5ddbdce60a5dc70efe693b04c76e976288f5831323ca195b05b06b0ff193d9de338001f81014b50669f5ad1d683123648b2117d56285eadbb5709482b5684e73abf73de1f78e228fab86b5a05c4193fac8a56dcbeb9d06639b1f3c3f10ae6ba119ac3740c23390963608be286a71d65e2706120df5b95991d0c32b40062c888bfabe87e9d604c4cdf3e6a748ade6ec26606ea7bd403d9164c45196f992a5a64fa1923ab53ac991b4da0e8364655ce5345a981ece495d91e3b0083d8967b8a6f597275def352aa1bd7836ea47c72e3e2c7faf140a827af8b26b0e6218d0bc642e5e7930b83cc535f431141db89841a5fc55ffb1f0a0b2ac9a4a96a6887cc1679626332e05937a787c450769cc59ec04c5794d00acd6deb72527775f7abd653f7c4143a38504055b24d7602fad3eda3422e44ed5b0cca1d8312f6b1603427583a48bec068355dddc0ee784bdda7b825d15afba068c31a6bb16ff72d81c0b7526646080ae2b8b917002a5ee04abf99f0412d09f9b0007ec8c76d8b4469cc3a8ea6b92957921a9e9ba464088290f04706681c80242411dc3f160e51e1b83f3f4f7d098a66dfb33a67b0018c26129d503336217fcfd422f2f36eaf345f22b39328642b6d645959f08355902707cb651fbac1d9b8aace14e37347f510794a6aa0940c9c0f4c02123e4782cc08e05506d1ac5bfcdce134956fd6f3bd3fd1cff11b34958a9cf08a21f02c6a773f1b3df2236fea4a355998e67d4c79b6635a43bdcf0c3a29f0ab6d36db9ef9133b5821779c1c05a33a6bf9e285f7b0df3e27ea1a38b0886f4deab576e0bba1c370be9e6de3d922ee6690bb2221ae79f33dcda184e58d797dc2cf85a9768b630188f6d4cf6e04076db978aa81bbb8822f3dcdb597e2cf0dbc19b8a594cd62e938de61846c056f84b8b2cb0da484172d15392e6635d5f140fb7529bc5ad48d8fb37a6560ef5a744ea037baf970979e956a2a014fdd8e34e355b2b46a4061e17d3f07ec6241f06fb121c4678c0d68c535ac0092214e5bcf9b561025cfbe83e8d0b424dce25b8691213946baedc1f49f45372733776143859bda806dd19d7658c5be3d8a9f3845a6300fe0488ad6296f2dc8f582df0f0fca8cafeae24acac4d1c1f960a9552ff43e10e77eb74f95daf381fdf7efe79f2c6fb9aa06d530ffda9e2ac17330574bb8d46b74d7aca017477b909a4f6d671504f02e8b8affbd68d1fdbb31d23add5101d5a0f7e884129c17f82d6848124e466f84ac56c6f31ab73b2c04e4d4bb53e8f23a2f0aa74c896496577f55860f8a5df67a8233d90b1b42d8553e77af79c5e9807e3fd800f56f1d16563b12d0727bb3e6c4c3826e88206650b0b3e6e1d786e49dfc7fb1f1386a446c5cb58c40ac2031302c1890d8296c71a96d3ad24936ace4984a5f66e810e3f01825db3b848be61a9882dca07acd3b9965f26d0b4fdbb0626736de0ee50396aad8f60c03dbfbaac956f1a5d29e6655b90853caaab44461e5b7676e1bea3398f088ebe1ae8468e412ac825e84186138ada8fa2971eb65fd77a987bbef513a8db38a186cfd9fc9c12352456a347344ae4791fbcfb07642a6fc000c9f3db872ae6c1bb41e089b3945bb5e71211c0e6b66b149c6267489d3922cde00e2eabcef3f88195a7d341d8dd696df8c415bed1cc920da79acf04f49d510ad33e41e757976d1767fa5a96ebd3e62c89b49510871642f09f105cd5a744a3e5378a38fc381a5976d39a0b9c09503c686584dfb60b3dce9e9cacdeb169af8aff8b146c6a93328f9966fc1558a2e6dd11ca4375ca8dd66265a34364af6cc6805a6cf59b9e07d86c3fa25214f691c76ae5ba7910ff7c1b842cf3521cb5d68f40ee81a21feed0dfefc65b7837cf4fdf682db0608a09584a96cb30ed3c602adc6bee9c775c9dd051bdad64d41d55ad480daee48ff44471778ab868379f077ea12e3cb29aa0cd7446e5a0b31bed3ecf3ef431de0386db7086a0597c714e4f258691a587c7b969116b450d61c8152f8e84df0bb677cff7ac33e45837e5453db4658d1f22641321ea9bdca1873cf3fbad49026b9923bc270e228a413517db1cba135e7f64757a0e73a1384916ecaf83ab4600357f22ce174253e7be17fa12a4632941879fbe0de6744cb4ad6c6d673419a0f6f95b88598c7395648ec5e4161fe6bc0e1b1c8479ed5f8cb6cf8ca0739595cccac06f8756a86e6e6dce1190bbff4a1b14790a8b7e7f966182b539918d06475b36da278d3c5ddbdce60a5dc70efe693b04c76e976288f5831323ca195b05b06b0ff193d9de338001f81014b50669f5ad1d683123648b2117d56285eadbb5709482b5684e73abf73de1f78e228fab86b5a05c4193fac8a56dcbeb9d06639b1f3c3f10ae6ba119ac3740c23390963608be286a71d65e2706120df5b95991d0c32b40062c888bfabe87e9d604c4cdf3e6a748ade6ec26606ea7bd403d9164c45196f992a5a64fa1923ab53ac991b4da0e8364655ce5345a981ece495d91e3b0083d8967b8a6f597275def352aa1bd7836ea47c72e3e2c7faf140a827af8b26b0e6218d0bc642e5e7930b83cc535f431141db89841a5fc55ffb1f0a0b2ac9a4a96a6887cc1679626332e05937a787c450769cc59ec04c5794d00acd6deb72527775f7abd653f7c4143a38504055b24d7602fad3eda3422e44ed5b0cca1d8312f6b1603427583a48bec068355dddc0ee784bdda7b825d15afba068c31a6bb16ff72d81c0b7526646080ae2b8b917002a5ee04abf99f0412d09f9b0007ec8c76d8b4469cc3a8ea6b92957921a9e9ba464088290f04706681c80242411dc3f160e51e1b83f3f4f7d098a66dfb33a67b0018c26129d503336217fcfd422f2f36eaf345f22b39328642b6d645959f08355902707cb651fbac1d9b8aace14e37347f510794a6aa0940c9c0f4c02123e4782cc08e05506d1ac5bfcdce134956fd6f3bd3fd1cff11b34958a9cf08a21f02c6a773f1b3df2236fea4a355998e67d4c79b6635a43bdcf0c3a29f0ab6d36db9ef9133b5821779c1c05a33a6bf9e285f7b0df3e27ea1a38b0886f4deab576e0bba1c370be9e6de3d922ee6690bb2221ae79f33dcda184e58d797dc2cf85a9768b630188f6d4cf6e04076db978aa81bbb8822f3dcdb597e2cf0dbc19b8a594cd62e938de61846c056f84b8b2cb0da484172d15392e6635d5f140fb7529bc5ad48d8fb37a6560ef5a744ea037baf970979e956a2a014fdd8e34e355b2b46a4061e17d3f07ec6241f06fb121c4678c0d68c535ac0092214e5bcf9b561025cfbe83e8d0b424dce25b8691213946baedc1f49f45372733776143859bda806dd19d7658c5be3d8a9f3845a6300fe0488ad6296f2dc8f582df0f0fca8cafeae24acac4d1c1f960a9552ff43e10e77eb74f95daf381fdf7efe79f2c6fb9aa06d530ffda9e2ac17330574bb8d46b74d7aca017477b909a4f6d671504f02e8b8affbd68d1fdbb31d23add5101d5a0f7e884129c17f82d6848124e466f84ac56c6f31ab73b2c04e4d4bb53e8f23a2f0aa74c896496577f55860f8a5df67a8233d90b1b42d8553e77af79c5e9807e3fd800f56f1d16563b12d0727bb3e6c4c3826e88206650b0b3e6e1d786e49dfc7fb1f1386a446c5cb58c40ac2031302c1890d8296c71a96d3ad24936ace4984a5f66e810e3f01825db3b848be61a9882dca07acd3b9965f26d0b4fdbb0626736de0ee50396aad8f60c03dbfbaac956f1a5d29e6655b90853caaab44461e5b7676e1bea3398f088ebe1ae8468e412ac825e84186138ada8fa2971eb65fd77a987bbef513a8db38a186cfd9fc9c12352456a347344ae4791fbcfb07642a6fc000c9f3db872ae6c1bb41e089b3945bb5e71211c0e6b66b149c6267489d3922cde00e2eabcef3f88195a7d341d8dd696df8c415bed1cc920da79acf04f49d510ad33e41e757976d1767fa5a96ebd3e62c89b49510871642f09f105cd5a744a3e5378a38fc381a5976d39a0b9c09503c686584dfb60b3dce9e9cacde\"\r\n\r\nputs \"running...\"\r\nputs \"=========\"\r\n\r\nBenchmark.ips do |x|\r\n  x.report(\"long string a -      Char\") { long_string.split('a', 10) }\r\n  x.report(\"long string a -    String\") { long_string.split(\"a\", 10) }\r\n  x.report(\"long string a - Ch -> Str\") { long_string.split_as_string('a', 10) }\r\nend\r\nputs \"---------\"\r\nBenchmark.ips do |x|\r\n  x.report(\"long string g -      Char\") { long_string.split('g', 10) }\r\n  x.report(\"long string g -    String\") { long_string.split(\"g\", 10) }\r\n  x.report(\"long string g - Ch -> Str\") { long_string.split_as_string('g', 10) }\r\nend\r\nputs \"---------\"\r\nBenchmark.ips do |x|\r\n  x.report(\"short string s -      Char\") { short_string.split('s', 10) }\r\n  x.report(\"short string s -    String\") { short_string.split(\"s\", 10) }\r\n  x.report(\"short string s - Ch -> Str\") { short_string.split_as_string('s', 10) }\r\nend\r\nputs \"---------\"\r\nBenchmark.ips do |x|\r\n  x.report(\"short string i -      Char\") { short_string.split('i', 10) }\r\n  x.report(\"short string i -    String\") { short_string.split(\"i\", 10) }\r\n  x.report(\"short string i - Ch -> Str\") { short_string.split_as_string('i', 10) }\r\nend\r\n```\r\n\r\nAnd the result, from two runs:\r\n\r\n```\r\n~/projects/crystal $ crystal run str_split.cr\r\nrunning...\r\n=========\r\nlong string a -      Char 111.32k (±11.44%)  1.03× slower\r\nlong string a -    String 111.72k (±11.89%)  1.03× slower\r\nlong string a - Ch -> Str 114.71k (± 5.91%)       fastest\r\n---------\r\nlong string g -      Char   7.84k (± 5.83%)  1.84× slower\r\nlong string g -    String  13.93k (± 9.83%)  1.04× slower\r\nlong string g - Ch -> Str  14.46k (± 6.18%)       fastest\r\n---------\r\nshort string s -      Char 947.08k (±13.31%)  1.33× slower\r\nshort string s -    String   1.26M (± 8.65%)       fastest\r\nshort string s - Ch -> Str   1.12M (± 7.44%)  1.12× slower\r\n---------\r\nshort string i -      Char   1.15M (±10.26%)  1.26× slower\r\nshort string i -    String   1.44M (± 5.69%)       fastest\r\nshort string i - Ch -> Str   1.17M (± 9.72%)  1.23× slower\r\n~/projects/crystal $ crystal run str_split.cr\r\nrunning...\r\n=========\r\nlong string a -      Char 112.11k (±13.38%)  1.05× slower\r\nlong string a -    String 117.54k (±10.65%)       fastest\r\nlong string a - Ch -> Str  77.58k (±19.36%)  1.52× slower\r\n---------\r\nlong string g -      Char   7.43k (± 9.46%)  2.01× slower\r\nlong string g -    String  14.93k (± 1.23%)       fastest\r\nlong string g - Ch -> Str   14.9k (± 0.73%)  1.00× slower\r\n---------\r\nshort string s -      Char   1.09M (± 4.50%)  1.23× slower\r\nshort string s -    String   1.34M (± 2.17%)       fastest\r\nshort string s - Ch -> Str   1.17M (± 2.81%)  1.14× slower\r\n---------\r\nshort string i -      Char    1.2M (± 4.49%)  1.17× slower\r\nshort string i -    String   1.41M (± 9.07%)       fastest\r\nshort string i - Ch -> Str   1.26M (± 5.34%)  1.12× slower\r\n```"},"comment":{"url":"https://api.github.com/repos/manastech/crystal/issues/comments/144092500","html_url":"https://github.com/manastech/crystal/pull/1632#issuecomment-144092500","issue_url":"https://api.github.com/repos/manastech/crystal/issues/1632","id":144092500,"user":{"login":"rmosolgo","id":2231765,"avatar_url":"https://avatars.githubusercontent.com/u/2231765?v=3","gravatar_id":"","url":"https://api.github.com/users/rmosolgo","html_url":"https://github.com/rmosolgo","followers_url":"https://api.github.com/users/rmosolgo/followers","following_url":"https://api.github.com/users/rmosolgo/following{/other_user}","gists_url":"https://api.github.com/users/rmosolgo/gists{/gist_id}","starred_url":"https://api.github.com/users/rmosolgo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rmosolgo/subscriptions","organizations_url":"https://api.github.com/users/rmosolgo/orgs","repos_url":"https://api.github.com/users/rmosolgo/repos","events_url":"https://api.github.com/users/rmosolgo/events{/privacy}","received_events_url":"https://api.github.com/users/rmosolgo/received_events","type":"User","site_admin":false},"created_at":"2015-09-29T15:21:03Z","updated_at":"2015-09-29T15:21:03Z","body":"You're right! Thanks for the tip about `--release`, I'll keep that in mind for the future. \r\n\r\nHere's the output:\r\n\r\n```\r\n~/projects/crystal $ crystal build --release str_split.cr\r\n~/projects/crystal $ ./str_split\r\nrunning...\r\n=========\r\nlong string a -      Char 139.95k (±13.17%)  1.06× slower\r\nlong string a -    String 148.14k (±14.12%)       fastest\r\nlong string a - Ch -> Str 125.02k (±18.73%)  1.18× slower\r\n---------\r\nlong string g -      Char  38.31k (± 2.40%)       fastest\r\nlong string g -    String  23.97k (± 7.58%)  1.60× slower\r\nlong string g - Ch -> Str  24.16k (± 6.28%)  1.59× slower\r\n---------\r\nshort string s -      Char   2.26M (± 1.90%)  1.01× slower\r\nshort string s -    String   2.29M (± 3.34%)       fastest\r\nshort string s - Ch -> Str   1.82M (± 7.47%)  1.25× slower\r\n---------\r\nshort string i -      Char   2.42M (± 2.44%) fastest\r\nshort string i -    String   2.31M (± 4.39%)  1.05× slower\r\nshort string i - Ch -> Str   1.96M (±12.93%)  1.23× slower\r\n```"}}