@@ -145,3 +145,156 @@ public func run_Dictionary(scale: Int) {
145
145
CheckResults ( count == N*541,
146
146
" IncorrectResults in DictTest: \( count) != \( N*541) . " )
147
147
}
148
+
149
+ class Box < T : Hashable where T : Equatable > : Hashable {
150
+ var value : T
151
+
152
+ init ( _ v: T ) {
153
+ value = v
154
+ }
155
+
156
+ var hashValue : Int {
157
+ return value. hashValue
158
+ }
159
+ }
160
+
161
+ extension Box : Equatable {
162
+ }
163
+
164
+ func == < T: Equatable > ( lhs: Box < T > , rhs: Box < T > ) -> Bool {
165
+ return lhs. value == rhs. value
166
+ }
167
+
168
+ @inline ( never)
169
+ public func run_DictionaryOfObjects( scale: Int ) {
170
+ let Input = [
171
+ // Text from http://en.wikipedia.org/wiki/Hash_table
172
+ " hash " , " table " ,
173
+ " in " , " computing " , " a " , " hash " , " table " , " also " , " hash " , " map " , " is " ,
174
+ " a " , " data " , " structure " , " used " , " to " , " implement " , " an " , " associative " ,
175
+ " array " , " a " , " structure " , " that " , " can " , " map " , " keys " , " to " , " values " ,
176
+ " a " , " hash " , " table " , " uses " , " a " , " hash " , " function " , " to " , " compute " ,
177
+ " an " , " index " , " into " , " an " , " array " , " of " , " buckets " , " or " , " slots " ,
178
+ " from " , " which " , " the " , " correct " , " value " , " can " , " be " , " found " ,
179
+ " ideally " , " the " , " hash " , " function " , " will " , " assign " , " each " , " key " ,
180
+ " to " , " a " , " unique " , " bucket " , " but " , " this " , " situation " , " is " ,
181
+ " rarely " , " achievable " , " in " , " practice " , " usually " , " some " , " keys " ,
182
+ " will " , " hash " , " to " , " the " , " same " , " bucket " , " instead " , " most " , " hash " ,
183
+ " table " , " designs " , " assume " , " that " , " hash " , " collisions " , " different " ,
184
+ " keys " , " that " , " are " , " assigned " , " by " , " the " , " hash " , " function " , " to " ,
185
+ " the " , " same " , " bucket " , " will " , " occur " , " and " , " must " , " be " ,
186
+ " accommodated " , " in " , " some " , " way " , " in " , " a " , " well " , " dimensioned " ,
187
+ " hash " , " table " , " the " , " average " , " cost " , " number " , " of " ,
188
+ " instructions " , " for " , " each " , " lookup " , " is " , " independent " , " of " ,
189
+ " the " , " number " , " of " , " elements " , " stored " , " in " , " the " , " table " ,
190
+ " many " , " hash " , " table " , " designs " , " also " , " allow " , " arbitrary " ,
191
+ " insertions " , " and " , " deletions " , " of " , " key " , " value " , " pairs " , " at " ,
192
+ " amortized " , " constant " , " average " , " cost " , " per " , " operation " , " in " ,
193
+ " many " , " situations " , " hash " , " tables " , " turn " , " out " , " to " , " be " ,
194
+ " more " , " efficient " , " than " , " search " , " trees " , " or " , " any " , " other " ,
195
+ " table " , " lookup " , " structure " , " for " , " this " , " reason " , " they " , " are " ,
196
+ " widely " , " used " , " in " , " many " , " kinds " , " of " , " computer " , " software " ,
197
+ " particularly " , " for " , " associative " , " arrays " , " database " , " indexing " ,
198
+ " caches " , " and " , " sets " ,
199
+
200
+ " hashing " ,
201
+ " the " , " idea " , " of " , " hashing " , " is " , " to " , " distribute " , " the " ,
202
+ " entries " , " key " , " value " , " pairs " , " across " , " an " , " array " , " of " ,
203
+ " buckets " , " given " , " a " , " key " , " the " , " algorithm " , " computes " , " an " ,
204
+ " index " , " that " , " suggests " , " where " , " the " , " entry " , " can " , " be " ,
205
+ " found " , " index " , " f " , " key " , " array " , " size " , " often " , " this " , " is " ,
206
+ " done " , " in " , " two " , " steps " , " hash " , " hashfunc " , " key " , " index " , " hash " ,
207
+ " array " , " size " , " in " , " this " , " method " , " the " , " hash " , " is " ,
208
+ " independent " , " of " , " the " , " array " , " size " , " and " , " it " , " is " , " then " ,
209
+ " reduced " , " to " , " an " , " index " , " a " , " number " , " between " , " and " , " array " ,
210
+ " size " , " using " , " the " , " modulus " , " operator " , " in " , " the " , " case " ,
211
+ " that " , " the " , " array " , " size " , " is " , " a " , " power " , " of " , " two " , " the " ,
212
+ " remainder " , " operation " , " is " , " reduced " , " to " , " masking " , " which " ,
213
+ " improves " , " speed " , " but " , " can " , " increase " , " problems " , " with " , " a " ,
214
+ " poor " , " hash " , " function " ,
215
+
216
+ " choosing " , " a " , " good " , " hash " , " function " ,
217
+ " a " , " good " , " hash " , " function " , " and " , " implementation " , " algorithm " ,
218
+ " are " , " essential " , " for " , " good " , " hash " , " table " , " performance " , " but " ,
219
+ " may " , " be " , " difficult " , " to " , " achieve " , " a " , " basic " , " requirement " ,
220
+ " is " , " that " , " the " , " function " , " should " , " provide " , " a " , " uniform " ,
221
+ " distribution " , " of " , " hash " , " values " , " a " , " non " , " uniform " ,
222
+ " distribution " , " increases " , " the " , " number " , " of " , " collisions " , " and " ,
223
+ " the " , " cost " , " of " , " resolving " , " them " , " uniformity " , " is " ,
224
+ " sometimes " , " difficult " , " to " , " ensure " , " by " , " design " , " but " , " may " ,
225
+ " be " , " evaluated " , " empirically " , " using " , " statistical " , " tests " , " e " ,
226
+ " g " , " a " , " pearson " , " s " , " chi " , " squared " , " test " , " for " , " discrete " ,
227
+ " uniform " , " distributions " , " the " , " distribution " , " needs " , " to " , " be " ,
228
+ " uniform " , " only " , " for " , " table " , " sizes " , " that " , " occur " , " in " , " the " ,
229
+ " application " , " in " , " particular " , " if " , " one " , " uses " , " dynamic " ,
230
+ " resizing " , " with " , " exact " , " doubling " , " and " , " halving " , " of " , " the " ,
231
+ " table " , " size " , " s " , " then " , " the " , " hash " , " function " , " needs " , " to " ,
232
+ " be " , " uniform " , " only " , " when " , " s " , " is " , " a " , " power " , " of " , " two " ,
233
+ " on " , " the " , " other " , " hand " , " some " , " hashing " , " algorithms " , " provide " ,
234
+ " uniform " , " hashes " , " only " , " when " , " s " , " is " , " a " , " prime " , " number " ,
235
+ " for " , " open " , " addressing " , " schemes " , " the " , " hash " , " function " ,
236
+ " should " , " also " , " avoid " , " clustering " , " the " , " mapping " , " of " , " two " ,
237
+ " or " , " more " , " keys " , " to " , " consecutive " , " slots " , " such " , " clustering " ,
238
+ " may " , " cause " , " the " , " lookup " , " cost " , " to " , " skyrocket " , " even " , " if " ,
239
+ " the " , " load " , " factor " , " is " , " low " , " and " , " collisions " , " are " ,
240
+ " infrequent " , " the " , " popular " , " multiplicative " , " hash " , " 3 " , " is " ,
241
+ " claimed " , " to " , " have " , " particularly " , " poor " , " clustering " ,
242
+ " behavior " , " cryptographic " , " hash " , " functions " , " are " , " believed " ,
243
+ " to " , " provide " , " good " , " hash " , " functions " , " for " , " any " , " table " ,
244
+ " size " , " s " , " either " , " by " , " modulo " , " reduction " , " or " , " by " , " bit " ,
245
+ " masking " , " they " , " may " , " also " , " be " , " appropriate " , " if " , " there " ,
246
+ " is " , " a " , " risk " , " of " , " malicious " , " users " , " trying " , " to " ,
247
+ " sabotage " , " a " , " network " , " service " , " by " , " submitting " , " requests " ,
248
+ " designed " , " to " , " generate " , " a " , " large " , " number " , " of " , " collisions " ,
249
+ " in " , " the " , " server " , " s " , " hash " , " tables " , " however " , " the " , " risk " ,
250
+ " of " , " sabotage " , " can " , " also " , " be " , " avoided " , " by " , " cheaper " ,
251
+ " methods " , " such " , " as " , " applying " , " a " , " secret " , " salt " , " to " , " the " ,
252
+ " data " , " or " , " using " , " a " , " universal " , " hash " , " function " ,
253
+
254
+ " perfect " , " hash " , " function " ,
255
+ " if " , " all " , " keys " , " are " , " known " , " ahead " , " of " , " time " , " a " ,
256
+ " perfect " , " hash " , " function " , " can " , " be " , " used " , " to " , " create " , " a " ,
257
+ " perfect " , " hash " , " table " , " that " , " has " , " no " , " collisions " , " if " ,
258
+ " minimal " , " perfect " , " hashing " , " is " , " used " , " every " , " location " , " in " ,
259
+ " the " , " hash " , " table " , " can " , " be " , " used " , " as " , " well " , " perfect " ,
260
+ " hashing " , " allows " , " for " , " constant " , " time " , " lookups " , " in " , " the " ,
261
+ " worst " , " case " , " this " , " is " , " in " , " contrast " , " to " , " most " ,
262
+ " chaining " , " and " , " open " , " addressing " , " methods " , " where " , " the " ,
263
+ " time " , " for " , " lookup " , " is " , " low " , " on " , " average " , " but " , " may " ,
264
+ " be " , " very " , " large " , " proportional " , " to " , " the " , " number " , " of " ,
265
+ " entries " , " for " , " some " , " sets " , " of " , " keys "
266
+ ]
267
+
268
+ var Dict : Dictionary < Box < String > , Box < Bool > > = [ : ]
269
+ let N = 5 * scale
270
+
271
+ // Check performance of filling the dictionary:
272
+ for _ in 1 ... N {
273
+ Dict = [ : ]
274
+ for word in Input {
275
+ Dict [ Box ( word) ] = Box ( true ) ;
276
+ }
277
+ }
278
+ CheckResults ( Dict . count == 270 ,
279
+ " IncorrectResults in DictTest: \( Dict . count) != 270. " )
280
+
281
+ // Check performance of searching in the dictionary:
282
+ // Fill the dictionary with words from the first half of the text
283
+ Dict = [ : ]
284
+ for i in 0 ..< Input . count/ 2 {
285
+ let word = Input [ i]
286
+ Dict [ Box ( word) ] = Box ( true )
287
+ }
288
+
289
+ // Count number of words from the first half in the entire text
290
+ var count = 0
291
+ for _ in 1 ... N {
292
+ for word in Input {
293
+ if Dict [ Box ( word) ] != nil {
294
+ count += 1
295
+ }
296
+ }
297
+ }
298
+ CheckResults ( count == N*541,
299
+ " IncorrectResults in DictTestAllObjects: \( count) != \( N*541) . " )
300
+ }
0 commit comments