]> gitweb.factorcode.org Git - factor.git/blob - extra/mongodb/benchmark/benchmark.factor
f9e6ff552626950adf8abc67fefa3663df175d3b
[factor.git] / extra / mongodb / benchmark / benchmark.factor
1 USING: calendar math fry kernel assocs math.ranges bson.reader io.streams.byte-array
2 sequences formatting combinators namespaces io tools.time prettyprint io.encodings.binary
3 accessors words mongodb.driver strings math.parser bson.writer
4 hashtables ;
5 FROM: mongodb.driver => find ;
6 FROM: memory => gc ;
7
8 IN: mongodb.benchmark
9
10 SYMBOL: collection
11
12 : get* ( symbol default -- value )
13     [ get ] dip or ; inline
14
15 : ensure-number ( v -- n )
16     dup string? [ string>number ] when ; inline
17
18 : trial-size ( -- size )
19     "per-trial" 5000 get* ensure-number ; inline flushable
20
21 : batch-size ( -- size )
22     "batch-size" 100 get* ensure-number ; inline flushable
23
24 TUPLE: result doc collection index batch lasterror ;
25
26 : <result> ( -- ) result new result set ; inline
27
28
29 CONSTANT: CHECK-KEY f
30
31 CONSTANT: DOC-SMALL H{ }
32
33 CONSTANT: DOC-MEDIUM H{ { "integer" 5 }
34                         { "number" 5.05 }
35                         { "boolean" f }
36                         { "array"
37                           { "test" "benchmark" } } }
38
39 CONSTANT: DOC-LARGE H{ { "base_url" "http://www.example.com/test-me" }
40                        { "total_word_count" 6743 }
41                        { "access_time" f }
42                        { "meta_tags" H{ { "description" "i am a long description string" }
43                                         { "author" "Holly Man" }
44                                         { "dynamically_created_meta_tag" "who know\n what" } } }
45                        { "page_structure" H{ { "counted_tags" 3450 }
46                                              { "no_of_js_attached" 10 }
47                                              { "no_of_images" 6 } } }
48                        { "harvested_words" { "10gen" "web" "open" "source" "application" "paas"
49                                              "platform-as-a-service" "technology" "helps"
50                                              "developers" "focus" "building" "mongodb" "mongo"
51                                              "10gen" "web" "open" "source" "application" "paas"
52                                              "platform-as-a-service" "technology" "helps"
53                                              "developers" "focus" "building" "mongodb" "mongo"
54                                              "10gen" "web" "open" "source" "application" "paas"
55                                              "platform-as-a-service" "technology" "helps"
56                                              "developers" "focus" "building" "mongodb" "mongo"
57                                              "10gen" "web" "open" "source" "application" "paas"
58                                              "platform-as-a-service" "technology" "helps"
59                                              "developers" "focus" "building" "mongodb" "mongo"
60                                              "10gen" "web" "open" "source" "application" "paas"
61                                              "platform-as-a-service" "technology" "helps"
62                                              "developers" "focus" "building" "mongodb" "mongo"
63                                              "10gen" "web" "open" "source" "application" "paas"
64                                              "platform-as-a-service" "technology" "helps"
65                                              "developers" "focus" "building" "mongodb" "mongo"
66                                              "10gen" "web" "open" "source" "application" "paas"
67                                              "platform-as-a-service" "technology" "helps"
68                                              "developers" "focus" "building" "mongodb" "mongo"
69                                              "10gen" "web" "open" "source" "application" "paas"
70                                              "platform-as-a-service" "technology" "helps"
71                                              "developers" "focus" "building" "mongodb" "mongo"
72                                              "10gen" "web" "open" "source" "application" "paas"
73                                              "platform-as-a-service" "technology" "helps"
74                                              "developers" "focus" "building" "mongodb" "mongo"
75                                              "10gen" "web" "open" "source" "application" "paas"
76                                              "platform-as-a-service" "technology" "helps"
77                                              "developers" "focus" "building" "mongodb" "mongo"
78                                              "10gen" "web" "open" "source" "application" "paas"
79                                              "platform-as-a-service" "technology" "helps"
80                                              "developers" "focus" "building" "mongodb" "mongo"
81                                              "10gen" "web" "open" "source" "application" "paas"
82                                              "platform-as-a-service" "technology" "helps"
83                                              "developers" "focus" "building" "mongodb" "mongo"
84                                              "10gen" "web" "open" "source" "application" "paas"
85                                              "platform-as-a-service" "technology" "helps"
86                                              "developers" "focus" "building" "mongodb" "mongo"
87                                              "10gen" "web" "open" "source" "application" "paas"
88                                              "platform-as-a-service" "technology" "helps"
89                                              "developers" "focus" "building" "mongodb" "mongo"
90                                              "10gen" "web" "open" "source" "application" "paas"
91                                              "platform-as-a-service" "technology" "helps"
92                                              "developers" "focus" "building" "mongodb" "mongo"
93                                              "10gen" "web" "open" "source" "application" "paas"
94                                              "platform-as-a-service" "technology" "helps"
95                                              "developers" "focus" "building" "mongodb" "mongo"
96                                              "10gen" "web" "open" "source" "application" "paas"
97                                              "platform-as-a-service" "technology" "helps"
98                                              "developers" "focus" "building" "mongodb" "mongo"
99                                              "10gen" "web" "open" "source" "application" "paas"
100                                              "platform-as-a-service" "technology" "helps"
101                                              "developers" "focus" "building" "mongodb" "mongo"
102                                              "10gen" "web" "open" "source" "application" "paas"
103                                              "platform-as-a-service" "technology" "helps"
104                                              "developers" "focus" "building" "mongodb" "mongo"
105                                              "10gen" "web" "open" "source" "application" "paas"
106                                              "platform-as-a-service" "technology" "helps"
107                                              "developers" "focus" "building" "mongodb" "mongo" } } }
108
109 : set-doc ( name -- )
110     [ result ] dip '[ _ >>doc ] change ; inline
111
112 : small-doc ( -- quot )
113     "small" set-doc [ ] ; inline
114
115 : medium-doc ( -- quot )
116     "medium" set-doc [ ] ; inline
117
118 : large-doc ( -- quot )
119     "large" set-doc [ ] ; inline
120
121 : small-doc-prepare ( -- quot: ( i -- doc ) )
122     small-doc drop
123     '[ "x" DOC-SMALL clone [ set-at ] keep ] ;
124
125 : medium-doc-prepare ( -- quot: ( i -- doc ) )
126     medium-doc drop
127     '[ "x" DOC-MEDIUM clone [ set-at ] keep ] ;
128
129 : large-doc-prepare ( -- quot: ( i -- doc ) )
130     large-doc drop
131     [ "x" DOC-LARGE clone [ set-at ] keep
132        [ now "access-time" ] dip
133        [ set-at ] keep ] ;
134
135 : (insert) ( quot: ( i -- doc ) collection -- )
136     [ trial-size ] 2dip
137     '[ _ call( i -- doc ) [ _ ] dip
138        result get lasterror>> [ save ] [ save-unsafe ] if ] each-integer ;
139
140 : (prepare-batch) ( i b quot: ( i -- doc ) -- batch-seq )
141     [ [ * ] keep 1 range boa ] dip
142     '[ _ call( i -- doc ) ] map ;
143
144 : (insert-batch) ( quot: ( i -- doc ) collection -- )
145     [ trial-size batch-size [ / ] keep ] 2dip
146     '[ _ _ (prepare-batch) [ _ ] dip
147        result get lasterror>> [ save ] [ save-unsafe ] if
148     ] each-integer ;
149
150 : bchar ( boolean -- char )
151     [ "t" ] [ "f" ] if ; inline
152
153 : collection-name ( -- collection )
154     collection "benchmark" get*
155     result get doc>>
156     result get index>> bchar
157     "%s-%s-%s" sprintf
158     [ [ result get ] dip >>collection drop ] keep ;
159
160 : prepare-collection ( -- collection )
161     collection-name
162     [ "_x_idx" drop-index ] keep
163     [ drop-collection ] keep
164     [ create-collection ] keep ;
165
166 : prepare-index ( collection -- )
167     "_x_idx" [ "x" asc ] key-spec <index-spec> t >>unique? ensure-index ;
168
169 : insert ( doc-quot: ( i -- doc ) -- quot: ( -- ) )
170     prepare-collection
171     result get index>> [ [ prepare-index ] keep ] when
172     result get batch>>
173     [ '[ _ _ (insert-batch) ] ] [ '[ _ _ (insert) ] ] if ;
174
175 : serialize ( doc-quot: ( i -- doc ) -- quot: ( -- ) )
176     '[ trial-size [ _ call( i -- doc ) assoc>bv drop ] each-integer ] ;
177
178 : deserialize ( doc-quot: ( i -- doc ) -- quot: ( -- ) )
179     [ 0 ] dip call( i -- doc ) assoc>bv
180     '[ trial-size [  _ binary [ H{ } stream>assoc drop ] with-byte-reader ] times ] ;
181
182 : check-for-key ( assoc key -- )
183     CHECK-KEY [ swap key? [ "ups... where's the key" throw ] unless ] [ 2drop ] if ;
184
185 : (check-find-result) ( result -- )
186     "x" check-for-key ; inline
187
188 : (find) ( cursor -- )
189     [ find [ (check-find-result) ] each (find) ] when* ; inline recursive
190
191 : find-one ( quot -- quot: ( -- ) )
192     drop
193     [ trial-size
194       collection-name
195       trial-size 2 / "x" associate
196       '[ _ _ <query> 1 limit (find) ] times ] ;
197
198 : find-all ( quot -- quot: ( -- ) )
199     drop
200     collection-name
201     H{ } clone
202     '[ _ _ <query> (find) ] ;
203
204 : find-range ( quot -- quot: ( -- ) )
205     drop
206     [ trial-size batch-size /i
207        collection-name
208        trial-size 2 / "$gt" H{ } clone [ set-at ] keep
209        [ trial-size 2 / batch-size + "$lt" ] dip [ set-at ] keep
210        "x" H{ } clone [ set-at ] keep
211        '[ _ _ <query> (find) ] times ] ;
212
213 : batch ( -- )
214     result [ t >>batch ] change ; inline
215
216 : index ( -- )
217     result [ t >>index ] change ; inline
218
219 : errcheck ( -- )
220     result [ t >>lasterror ] change ; inline
221
222 : print-result ( time -- )
223     [ result get [ collection>> ] keep
224       [ batch>> bchar ] keep
225       [ index>> bchar ] keep
226       lasterror>> bchar
227       trial-size ] dip
228       1000000000 / [ /i ] [ result get batch>> [ [ batch-size /i ] dip ] when /i ] 2bi
229     "%-18s: {batch:%s,index:%s;errchk:%s} %10s docs/s %10s ops/s"
230     sprintf print flush ;
231
232 : print-separator ( -- )
233     "---------------------------------------------------------------------------------" print flush ; inline
234
235 : print-separator-bold ( -- )
236     "=================================================================================" print flush ; inline
237
238 : print-header ( -- )
239     trial-size
240     batch-size
241     "MongoDB Factor Driver Benchmark\n%d ops per Trial, Batch-Size: %d"
242     sprintf print flush
243     print-separator-bold ;
244
245 : with-result ( options quot -- )
246     '[ <result> _ call( options -- time ) print-result ] with-scope ;
247
248 : [bench-quot] ( feat-seq op-word -- quot: ( doc-word -- ) )
249     '[ _ swap _
250        '[ [ [ _ execute( -- quot ) ] dip
251           [ execute( -- ) ] each _ execute( quot -- quot ) gc
252             benchmark ] with-result ] each
253        print-separator ] ;
254
255 : run-serialization-bench ( doc-word-seq feat-seq -- )
256     "Serialization Tests" print
257     print-separator-bold
258     \ serialize [bench-quot] '[ _ call( doc-word -- ) ] each ;
259
260 : run-deserialization-bench ( doc-word-seq feat-seq -- )
261     "Deserialization Tests" print
262     print-separator-bold
263     \ deserialize [bench-quot] '[ _ call( doc-word -- ) ] each ;
264
265 : run-insert-bench ( doc-word-seq feat-seq -- )
266     "Insert Tests" print
267     print-separator-bold
268     \ insert [bench-quot] '[ _ call( doc-word -- ) ] each ;
269
270 : run-find-one-bench ( doc-word-seq feat-seq -- )
271     "Query Tests - Find-One" print
272     print-separator-bold
273     \ find-one [bench-quot] '[ _ call( doc-word -- ) ] each ;
274
275 : run-find-all-bench ( doc-word-seq feat-seq -- )
276     "Query Tests - Find-All" print
277     print-separator-bold
278     \ find-all [bench-quot] '[ _ call( doc-word -- ) ] each ;
279
280 : run-find-range-bench ( doc-word-seq feat-seq -- )
281     "Query Tests - Find-Range" print
282     print-separator-bold
283     \ find-range [bench-quot] '[ _ call( doc-word -- ) ] each ;
284
285
286 : run-benchmarks ( -- )
287     "db" "db" get* "host" "127.0.0.1" get* "port" 27017 get* ensure-number <mdb>
288     [ print-header
289       ! serialization
290       { small-doc-prepare medium-doc-prepare
291         large-doc-prepare }
292       { { } } run-serialization-bench
293       ! deserialization
294       { small-doc-prepare medium-doc-prepare
295         large-doc-prepare }
296       { { } } run-deserialization-bench
297       ! insert
298       { small-doc-prepare medium-doc-prepare
299         large-doc-prepare }
300       { { } { index } { errcheck } { index errcheck }
301         { batch } { batch errcheck } { batch index errcheck }
302       } run-insert-bench
303       ! find-one
304       { small-doc medium-doc large-doc }
305       { { } { index } } run-find-one-bench
306       ! find-all
307       { small-doc medium-doc large-doc }
308       { { } { index } } run-find-all-bench
309       ! find-range
310       { small-doc medium-doc large-doc }
311       { { } { index } } run-find-range-bench
312     ] with-db ;
313
314 MAIN: run-benchmarks