├── README.md ├── bench_test.go ├── go.mod └── testdata ├── canada.json ├── citm.json ├── code.json ├── example.json ├── sample.json ├── twitter.json └── warandpeace.txt /README.md: -------------------------------------------------------------------------------- 1 | # Whitespace benchmarks 2 | 3 | ``` 4 | name time/op 5 | WhitespaceArray/canada.json-16 1.14ms ± 2% 6 | WhitespaceArray/code.json-16 981µs ± 2% 7 | WhitespaceArray/citm.json-16 880µs ± 2% 8 | WhitespaceArray/warandpeace.txt-16 1.71ms ± 1% 9 | WhitespaceArrayInlined/canada.json-16 1.05ms ± 2% 10 | WhitespaceArrayInlined/code.json-16 911µs ± 1% 11 | WhitespaceArrayInlined/citm.json-16 817µs ± 2% 12 | WhitespaceArrayInlined/warandpeace.txt-16 1.56ms ± 2% 13 | WhitespaceShift/canada.json-16 2.51ms ± 2% 14 | WhitespaceShift/code.json-16 2.17ms ± 2% 15 | WhitespaceShift/citm.json-16 1.92ms ± 1% 16 | WhitespaceShift/warandpeace.txt-16 3.74ms ± 2% 17 | WhitespaceShiftInlined/canada.json-16 2.29ms ± 5% 18 | WhitespaceShiftInlined/code.json-16 1.94ms ± 2% 19 | WhitespaceShiftInlined/citm.json-16 1.72ms ± 2% 20 | WhitespaceShiftInlined/warandpeace.txt-16 3.36ms ± 2% 21 | WhitespaceSwitch/canada.json-16 1.51ms ± 2% 22 | WhitespaceSwitch/code.json-16 1.31ms ± 2% 23 | WhitespaceSwitch/citm.json-16 1.72ms ± 1% 24 | WhitespaceSwitch/warandpeace.txt-16 6.65ms ± 2% 25 | WhitespaceIf/canada.json-16 1.00ms ± 1% 26 | WhitespaceIf/code.json-16 864µs ± 1% 27 | WhitespaceIf/citm.json-16 1.02ms ± 1% 28 | WhitespaceIf/warandpeace.txt-16 5.18ms ± 2% 29 | WhitespaceIfInlined/canada.json-16 1.00ms ± 1% 30 | WhitespaceIfInlined/code.json-16 862µs ± 2% 31 | WhitespaceIfInlined/citm.json-16 1.02ms ± 2% 32 | WhitespaceIfInlined/warandpeace.txt-16 5.18ms ± 2% 33 | 34 | name speed 35 | WhitespaceArray/canada.json-16 1.98GB/s ± 2% 36 | WhitespaceArray/code.json-16 1.98GB/s ± 2% 37 | WhitespaceArray/citm.json-16 1.96GB/s ± 2% 38 | WhitespaceArray/warandpeace.txt-16 1.97GB/s ± 1% 39 | WhitespaceArrayInlined/canada.json-16 2.14GB/s ± 2% 40 | WhitespaceArrayInlined/code.json-16 2.13GB/s ± 1% 41 | WhitespaceArrayInlined/citm.json-16 2.11GB/s ± 2% 42 | WhitespaceArrayInlined/warandpeace.txt-16 2.15GB/s ± 2% 43 | WhitespaceShift/canada.json-16 895MB/s ± 3% 44 | WhitespaceShift/code.json-16 894MB/s ± 3% 45 | WhitespaceShift/citm.json-16 899MB/s ± 1% 46 | WhitespaceShift/warandpeace.txt-16 899MB/s ± 2% 47 | WhitespaceShiftInlined/canada.json-16 983MB/s ± 4% 48 | WhitespaceShiftInlined/code.json-16 1.00GB/s ± 2% 49 | WhitespaceShiftInlined/citm.json-16 1.00GB/s ± 2% 50 | WhitespaceShiftInlined/warandpeace.txt-16 1.00GB/s ± 2% 51 | WhitespaceSwitch/canada.json-16 1.49GB/s ± 2% 52 | WhitespaceSwitch/code.json-16 1.48GB/s ± 2% 53 | WhitespaceSwitch/citm.json-16 1.01GB/s ± 1% 54 | WhitespaceSwitch/warandpeace.txt-16 506MB/s ± 2% 55 | WhitespaceIf/canada.json-16 2.25GB/s ± 1% 56 | WhitespaceIf/code.json-16 2.25GB/s ± 1% 57 | WhitespaceIf/citm.json-16 1.69GB/s ± 1% 58 | WhitespaceIf/warandpeace.txt-16 649MB/s ± 2% 59 | WhitespaceIfInlined/canada.json-16 2.25GB/s ± 1% 60 | WhitespaceIfInlined/code.json-16 2.25GB/s ± 2% 61 | WhitespaceIfInlined/citm.json-16 1.69GB/s ± 2% 62 | WhitespaceIfInlined/warandpeace.txt-16 648MB/s ± 2% 63 | ``` 64 | -------------------------------------------------------------------------------- /bench_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | "path/filepath" 6 | "testing" 7 | ) 8 | 9 | var fixtures = []struct { 10 | path string 11 | want int 12 | }{ 13 | {"canada.json", 33}, 14 | {"code.json", 3}, 15 | {"citm.json", 1227563}, 16 | {"warandpeace.txt", 649134}, 17 | } 18 | 19 | func BenchmarkWhitespace(b *testing.B) { 20 | b.Run("array", withFixtures(b, benchmarkWhitespaceArray)) 21 | b.Run("array (inlined)", withFixtures(b, benchmarkWhitespaceArrayInlined)) 22 | b.Run("check", withFixtures(b, benchmarkWhitespaceCheck)) 23 | b.Run("shift", withFixtures(b, benchmarkWhitespaceShift)) 24 | b.Run("shift (inlined)", withFixtures(b, benchmarkWhitespaceShiftInlined)) 25 | b.Run("switch", withFixtures(b, benchmarkWhitespaceSwitch)) 26 | b.Run("if", withFixtures(b, benchmarkWhitespaceIf)) 27 | b.Run("if (inlined)", withFixtures(b, benchmarkWhitespaceIfInlined)) 28 | b.Run("constant", withFixtures(b, benchmarkWhitespaceConstant)) 29 | } 30 | 31 | func withFixtures(b *testing.B, fn func(b *testing.B, input []byte, want int)) func(b *testing.B) { 32 | return func(b *testing.B) { 33 | for _, fix := range fixtures { 34 | data, err := os.ReadFile(filepath.Join("testdata", fix.path)) 35 | if err != nil { 36 | b.Fatal(err) 37 | } 38 | b.Run(fix.path, func(b *testing.B) { 39 | b.SetBytes(int64(len(data))) 40 | fn(b, data, fix.want) 41 | }) 42 | } 43 | } 44 | } 45 | 46 | var whitespace = [256]bool{ 47 | ' ': true, 48 | '\t': true, 49 | '\n': true, 50 | '\r': true, 51 | } 52 | 53 | func isWhitespaceArray(c byte) bool { 54 | return whitespace[c] 55 | } 56 | 57 | func benchmarkWhitespaceArray(b *testing.B, input []byte, want int) { 58 | for i := 0; i < b.N; i++ { 59 | n := 0 60 | for _, c := range input { 61 | if isWhitespaceArray(c) { 62 | n++ 63 | } 64 | } 65 | if n != want { 66 | b.Fatalf("expected: %v, got: %v", want, n) 67 | } 68 | } 69 | } 70 | 71 | func benchmarkWhitespaceArrayInlined(b *testing.B, input []byte, want int) { 72 | for i := 0; i < b.N; i++ { 73 | n := 0 74 | for _, c := range input { 75 | if whitespace[c] { 76 | n++ 77 | } 78 | } 79 | if n != want { 80 | b.Fatalf("expected: %v, got: %v", want, n) 81 | } 82 | } 83 | } 84 | 85 | func isWhitespaceShift(c byte) bool { 86 | const whitespace uint64 = 1<<' ' | 1<<'\t' | 1<<'\r' | 1<<'\n' 87 | return whitespace&(1< 0 88 | } 89 | 90 | func benchmarkWhitespaceShift(b *testing.B, input []byte, want int) { 91 | for i := 0; i < b.N; i++ { 92 | n := 0 93 | for _, c := range input { 94 | if isWhitespaceShift(c) { 95 | n++ 96 | } 97 | } 98 | if n != want { 99 | b.Fatalf("expected: %v, got: %v", want, n) 100 | } 101 | } 102 | } 103 | 104 | func benchmarkWhitespaceShiftInlined(b *testing.B, input []byte, want int) { 105 | const whitespace uint64 = 1<<' ' | 1<<'\t' | 1<<'\r' | 1<<'\n' 106 | for i := 0; i < b.N; i++ { 107 | n := 0 108 | for _, c := range input { 109 | if whitespace&(1< 0 { 110 | n++ 111 | } 112 | } 113 | if n != want { 114 | b.Fatalf("expected: %v, got: %v", want, n) 115 | } 116 | } 117 | } 118 | 119 | func isWhitespaceSwitch(c byte) bool { 120 | switch c { 121 | case ' ', '\n', '\t', '\r': 122 | return true 123 | default: 124 | return false 125 | } 126 | } 127 | 128 | func benchmarkWhitespaceSwitch(b *testing.B, input []byte, want int) { 129 | for i := 0; i < b.N; i++ { 130 | n := 0 131 | for _, c := range input { 132 | if isWhitespaceSwitch(c) { 133 | n++ 134 | } 135 | } 136 | if n != want { 137 | b.Fatalf("expected: %v, got: %v", want, n) 138 | } 139 | } 140 | } 141 | 142 | func isWhitespaceIf(c byte) bool { 143 | return c <= ' ' && (c == ' ' || c == '\n' || c == '\t' || c == '\r') 144 | } 145 | 146 | func benchmarkWhitespaceIf(b *testing.B, input []byte, want int) { 147 | for i := 0; i < b.N; i++ { 148 | n := 0 149 | for _, c := range input { 150 | if isWhitespaceIf(c) { 151 | n++ 152 | } 153 | } 154 | if n != want { 155 | b.Fatalf("expected: %v, got: %v", want, n) 156 | } 157 | } 158 | } 159 | 160 | func benchmarkWhitespaceIfInlined(b *testing.B, input []byte, want int) { 161 | for i := 0; i < b.N; i++ { 162 | n := 0 163 | for _, c := range input { 164 | if c <= ' ' && (c == ' ' || c == '\n' || c == '\t' || c == '\r') { 165 | n++ 166 | } 167 | } 168 | if n != want { 169 | b.Fatalf("expected: %v, got: %v", want, n) 170 | } 171 | } 172 | } 173 | 174 | func isWhitespaceCheck(c byte) bool { 175 | return c <= ' ' && whitespace[c] 176 | } 177 | 178 | func benchmarkWhitespaceCheck(b *testing.B, input []byte, want int) { 179 | for i := 0; i < b.N; i++ { 180 | n := 0 181 | for _, c := range input { 182 | if isWhitespaceCheck(c) { 183 | n++ 184 | } 185 | } 186 | if n != want { 187 | b.Fatalf("expected: %v, got: %v", want, n) 188 | } 189 | } 190 | } 191 | 192 | func benchmarkWhitespaceConstant(b *testing.B, input []byte, want int) { 193 | const whitespace = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\n\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 194 | 195 | for i := 0; i < b.N; i++ { 196 | n := 0 197 | for _, c := range input { 198 | if whitespace[c] == c { 199 | n++ 200 | } 201 | } 202 | if n != want { 203 | b.Fatalf("expected: %v, got: %v", want, n) 204 | } 205 | } 206 | } 207 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/davecheney/whitespace 2 | 3 | go 1.21 4 | -------------------------------------------------------------------------------- /testdata/example.json: -------------------------------------------------------------------------------- 1 | { 2 | "statuses": [ 3 | { 4 | "coordinates": null, 5 | "favorited": false, 6 | "truncated": false, 7 | "created_at": "Mon Sep 24 03:35:21 +0000 2012", 8 | "id_str": "250075927172759552", 9 | "entities": { 10 | "urls": [ 11 | 12 | ], 13 | "hashtags": [ 14 | { 15 | "text": "freebandnames", 16 | "indices": [ 17 | 20, 18 | 34 19 | ] 20 | } 21 | ], 22 | "user_mentions": [ 23 | 24 | ] 25 | }, 26 | "in_reply_to_user_id_str": null, 27 | "contributors": null, 28 | "text": "Aggressive Ponytail #freebandnames", 29 | "metadata": { 30 | "iso_language_code": "en", 31 | "result_type": "recent" 32 | }, 33 | "retweet_count": 0, 34 | "in_reply_to_status_id_str": null, 35 | "id": 250075927172759552, 36 | "geo": null, 37 | "retweeted": false, 38 | "in_reply_to_user_id": null, 39 | "place": null, 40 | "user": { 41 | "profile_sidebar_fill_color": "DDEEF6", 42 | "profile_sidebar_border_color": "C0DEED", 43 | "profile_background_tile": false, 44 | "name": "Sean Cummings", 45 | "profile_image_url": "http://a0.twimg.com/profile_images/2359746665/1v6zfgqo8g0d3mk7ii5s_normal.jpeg", 46 | "created_at": "Mon Apr 26 06:01:55 +0000 2010", 47 | "location": "LA, CA", 48 | "follow_request_sent": null, 49 | "profile_link_color": "0084B4", 50 | "is_translator": false, 51 | "id_str": "137238150", 52 | "entities": { 53 | "url": { 54 | "urls": [ 55 | { 56 | "expanded_url": null, 57 | "url": "", 58 | "indices": [ 59 | 0, 60 | 0 61 | ] 62 | } 63 | ] 64 | }, 65 | "description": { 66 | "urls": [ 67 | 68 | ] 69 | } 70 | }, 71 | "default_profile": true, 72 | "contributors_enabled": false, 73 | "favourites_count": 0, 74 | "url": null, 75 | "profile_image_url_https": "https://si0.twimg.com/profile_images/2359746665/1v6zfgqo8g0d3mk7ii5s_normal.jpeg", 76 | "utc_offset": -28800, 77 | "id": 137238150, 78 | "profile_use_background_image": true, 79 | "listed_count": 2, 80 | "profile_text_color": "333333", 81 | "lang": "en", 82 | "followers_count": 70, 83 | "protected": false, 84 | "notifications": null, 85 | "profile_background_image_url_https": "https://si0.twimg.com/images/themes/theme1/bg.png", 86 | "profile_background_color": "C0DEED", 87 | "verified": false, 88 | "geo_enabled": true, 89 | "time_zone": "Pacific Time (US & Canada)", 90 | "description": "Born 330 Live 310", 91 | "default_profile_image": false, 92 | "profile_background_image_url": "http://a0.twimg.com/images/themes/theme1/bg.png", 93 | "statuses_count": 579, 94 | "friends_count": 110, 95 | "following": null, 96 | "show_all_inline_media": false, 97 | "screen_name": "sean_cummings" 98 | }, 99 | "in_reply_to_screen_name": null, 100 | "source": "Twitter for Mac", 101 | "in_reply_to_status_id": null 102 | }, 103 | { 104 | "coordinates": null, 105 | "favorited": false, 106 | "truncated": false, 107 | "created_at": "Fri Sep 21 23:40:54 +0000 2012", 108 | "id_str": "249292149810667520", 109 | "entities": { 110 | "urls": [ 111 | 112 | ], 113 | "hashtags": [ 114 | { 115 | "text": "FreeBandNames", 116 | "indices": [ 117 | 20, 118 | 34 119 | ] 120 | } 121 | ], 122 | "user_mentions": [ 123 | 124 | ] 125 | }, 126 | "in_reply_to_user_id_str": null, 127 | "contributors": null, 128 | "text": "Thee Namaste Nerdz. #FreeBandNames", 129 | "metadata": { 130 | "iso_language_code": "pl", 131 | "result_type": "recent" 132 | }, 133 | "retweet_count": 0, 134 | "in_reply_to_status_id_str": null, 135 | "id": 249292149810667520, 136 | "geo": null, 137 | "retweeted": false, 138 | "in_reply_to_user_id": null, 139 | "place": null, 140 | "user": { 141 | "profile_sidebar_fill_color": "DDFFCC", 142 | "profile_sidebar_border_color": "BDDCAD", 143 | "profile_background_tile": true, 144 | "name": "Chaz Martenstein", 145 | "profile_image_url": "http://a0.twimg.com/profile_images/447958234/Lichtenstein_normal.jpg", 146 | "created_at": "Tue Apr 07 19:05:07 +0000 2009", 147 | "location": "Durham, NC", 148 | "follow_request_sent": null, 149 | "profile_link_color": "0084B4", 150 | "is_translator": false, 151 | "id_str": "29516238", 152 | "entities": { 153 | "url": { 154 | "urls": [ 155 | { 156 | "expanded_url": null, 157 | "url": "http://bullcityrecords.com/wnng/", 158 | "indices": [ 159 | 0, 160 | 32 161 | ] 162 | } 163 | ] 164 | }, 165 | "description": { 166 | "urls": [ 167 | 168 | ] 169 | } 170 | }, 171 | "default_profile": false, 172 | "contributors_enabled": false, 173 | "favourites_count": 8, 174 | "url": "http://bullcityrecords.com/wnng/", 175 | "profile_image_url_https": "https://si0.twimg.com/profile_images/447958234/Lichtenstein_normal.jpg", 176 | "utc_offset": -18000, 177 | "id": 29516238, 178 | "profile_use_background_image": true, 179 | "listed_count": 118, 180 | "profile_text_color": "333333", 181 | "lang": "en", 182 | "followers_count": 2052, 183 | "protected": false, 184 | "notifications": null, 185 | "profile_background_image_url_https": "https://si0.twimg.com/profile_background_images/9423277/background_tile.bmp", 186 | "profile_background_color": "9AE4E8", 187 | "verified": false, 188 | "geo_enabled": false, 189 | "time_zone": "Eastern Time (US & Canada)", 190 | "description": "You will come to Durham, North Carolina. I will sell you some records then, here in Durham, North Carolina. Fun will happen.", 191 | "default_profile_image": false, 192 | "profile_background_image_url": "http://a0.twimg.com/profile_background_images/9423277/background_tile.bmp", 193 | "statuses_count": 7579, 194 | "friends_count": 348, 195 | "following": null, 196 | "show_all_inline_media": true, 197 | "screen_name": "bullcityrecords" 198 | }, 199 | "in_reply_to_screen_name": null, 200 | "source": "web", 201 | "in_reply_to_status_id": null 202 | }, 203 | { 204 | "coordinates": null, 205 | "favorited": false, 206 | "truncated": false, 207 | "created_at": "Fri Sep 21 23:30:20 +0000 2012", 208 | "id_str": "249289491129438208", 209 | "entities": { 210 | "urls": [ 211 | 212 | ], 213 | "hashtags": [ 214 | { 215 | "text": "freebandnames", 216 | "indices": [ 217 | 29, 218 | 43 219 | ] 220 | } 221 | ], 222 | "user_mentions": [ 223 | 224 | ] 225 | }, 226 | "in_reply_to_user_id_str": null, 227 | "contributors": null, 228 | "text": "Mexican Heaven, Mexican Hell #freebandnames", 229 | "metadata": { 230 | "iso_language_code": "en", 231 | "result_type": "recent" 232 | }, 233 | "retweet_count": 0, 234 | "in_reply_to_status_id_str": null, 235 | "id": 249289491129438208, 236 | "geo": null, 237 | "retweeted": false, 238 | "in_reply_to_user_id": null, 239 | "place": null, 240 | "user": { 241 | "profile_sidebar_fill_color": "99CC33", 242 | "profile_sidebar_border_color": "829D5E", 243 | "profile_background_tile": false, 244 | "name": "Thomas John Wakeman", 245 | "profile_image_url": "http://a0.twimg.com/profile_images/2219333930/Froggystyle_normal.png", 246 | "created_at": "Tue Sep 01 21:21:35 +0000 2009", 247 | "location": "Kingston New York", 248 | "follow_request_sent": null, 249 | "profile_link_color": "D02B55", 250 | "is_translator": false, 251 | "id_str": "70789458", 252 | "entities": { 253 | "url": { 254 | "urls": [ 255 | { 256 | "expanded_url": null, 257 | "url": "", 258 | "indices": [ 259 | 0, 260 | 0 261 | ] 262 | } 263 | ] 264 | }, 265 | "description": { 266 | "urls": [ 267 | 268 | ] 269 | } 270 | }, 271 | "default_profile": false, 272 | "contributors_enabled": false, 273 | "favourites_count": 19, 274 | "url": null, 275 | "profile_image_url_https": "https://si0.twimg.com/profile_images/2219333930/Froggystyle_normal.png", 276 | "utc_offset": -18000, 277 | "id": 70789458, 278 | "profile_use_background_image": true, 279 | "listed_count": 1, 280 | "profile_text_color": "3E4415", 281 | "lang": "en", 282 | "followers_count": 63, 283 | "protected": false, 284 | "notifications": null, 285 | "profile_background_image_url_https": "https://si0.twimg.com/images/themes/theme5/bg.gif", 286 | "profile_background_color": "352726", 287 | "verified": false, 288 | "geo_enabled": false, 289 | "time_zone": "Eastern Time (US & Canada)", 290 | "description": "Science Fiction Writer, sort of. Likes Superheroes, Mole People, Alt. Timelines.", 291 | "default_profile_image": false, 292 | "profile_background_image_url": "http://a0.twimg.com/images/themes/theme5/bg.gif", 293 | "statuses_count": 1048, 294 | "friends_count": 63, 295 | "following": null, 296 | "show_all_inline_media": false, 297 | "screen_name": "MonkiesFist" 298 | }, 299 | "in_reply_to_screen_name": null, 300 | "source": "web", 301 | "in_reply_to_status_id": null 302 | }, 303 | { 304 | "coordinates": null, 305 | "favorited": false, 306 | "truncated": false, 307 | "created_at": "Fri Sep 21 22:51:18 +0000 2012", 308 | "id_str": "249279667666817024", 309 | "entities": { 310 | "urls": [ 311 | 312 | ], 313 | "hashtags": [ 314 | { 315 | "text": "freebandnames", 316 | "indices": [ 317 | 20, 318 | 34 319 | ] 320 | } 321 | ], 322 | "user_mentions": [ 323 | 324 | ] 325 | }, 326 | "in_reply_to_user_id_str": null, 327 | "contributors": null, 328 | "text": "The Foolish Mortals #freebandnames", 329 | "metadata": { 330 | "iso_language_code": "en", 331 | "result_type": "recent" 332 | }, 333 | "retweet_count": 0, 334 | "in_reply_to_status_id_str": null, 335 | "id": 249279667666817024, 336 | "geo": null, 337 | "retweeted": false, 338 | "in_reply_to_user_id": null, 339 | "place": null, 340 | "user": { 341 | "profile_sidebar_fill_color": "BFAC83", 342 | "profile_sidebar_border_color": "615A44", 343 | "profile_background_tile": true, 344 | "name": "Marty Elmer", 345 | "profile_image_url": "http://a0.twimg.com/profile_images/1629790393/shrinker_2000_trans_normal.png", 346 | "created_at": "Mon May 04 00:05:00 +0000 2009", 347 | "location": "Wisconsin, USA", 348 | "follow_request_sent": null, 349 | "profile_link_color": "3B2A26", 350 | "is_translator": false, 351 | "id_str": "37539828", 352 | "entities": { 353 | "url": { 354 | "urls": [ 355 | { 356 | "expanded_url": null, 357 | "url": "http://www.omnitarian.me", 358 | "indices": [ 359 | 0, 360 | 24 361 | ] 362 | } 363 | ] 364 | }, 365 | "description": { 366 | "urls": [ 367 | 368 | ] 369 | } 370 | }, 371 | "default_profile": false, 372 | "contributors_enabled": false, 373 | "favourites_count": 647, 374 | "url": "http://www.omnitarian.me", 375 | "profile_image_url_https": "https://si0.twimg.com/profile_images/1629790393/shrinker_2000_trans_normal.png", 376 | "utc_offset": -21600, 377 | "id": 37539828, 378 | "profile_use_background_image": true, 379 | "listed_count": 52, 380 | "profile_text_color": "000000", 381 | "lang": "en", 382 | "followers_count": 608, 383 | "protected": false, 384 | "notifications": null, 385 | "profile_background_image_url_https": "https://si0.twimg.com/profile_background_images/106455659/rect6056-9.png", 386 | "profile_background_color": "EEE3C4", 387 | "verified": false, 388 | "geo_enabled": false, 389 | "time_zone": "Central Time (US & Canada)", 390 | "description": "Cartoonist, Illustrator, and T-Shirt connoisseur", 391 | "default_profile_image": false, 392 | "profile_background_image_url": "http://a0.twimg.com/profile_background_images/106455659/rect6056-9.png", 393 | "statuses_count": 3575, 394 | "friends_count": 249, 395 | "following": null, 396 | "show_all_inline_media": true, 397 | "screen_name": "Omnitarian" 398 | }, 399 | "in_reply_to_screen_name": null, 400 | "source": "Twitter for iPhone", 401 | "in_reply_to_status_id": null 402 | } 403 | ], 404 | "search_metadata": { 405 | "max_id": 250126199840518145, 406 | "since_id": 24012619984051000, 407 | "refresh_url": "?since_id=250126199840518145&q=%23freebandnames&result_type=mixed&include_entities=1", 408 | "next_results": "?max_id=249279667666817023&q=%23freebandnames&count=4&include_entities=1&result_type=mixed", 409 | "count": 4, 410 | "completed_in": 0.035, 411 | "since_id_str": "24012619984051000", 412 | "query": "%23freebandnames", 413 | "max_id_str": "250126199840518145" 414 | } 415 | } 416 | --------------------------------------------------------------------------------