Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

RE: Biannual Competition to Improve Hashing Function

       Date: Thu, 8 Feb 2001 10:44:00 -0500
       Message-Id: <A5E22933E3D5D4118FFE00508BF373C706A52F@indyexch28.indy.tce.
       Date: Thu, 8 Feb 2001 15:02:47 -0500
       Message-Id: <A5E22933E3D5D4118FFE00508BF373C706A52B@indyexch28.indy.tce.

p4raw-id: //depot/perl@8750
  • Loading branch information...
commit a6fe520e69b81614f687efd2cdbfdcd1bb40e201 1 parent 682a4d6
Mark Fisher authored Nick Ing-Simmons committed
14 hv.h
@@ -43,14 +43,22 @@ struct xpvhv {
43 43 };
44 44
45 45 /* hash a key */
  46 +/* FYI: This is the "One-at-a-Time" algorithm by Bob Jenkins */
  47 +/* from requirements by Colin Plumb. */
  48 +/* (http://burtleburtle.net/bob/hash/doobs.html) */
46 49 #define PERL_HASH(hash,str,len) \
47 50 STMT_START { \
48 51 register const char *s_PeRlHaSh = str; \
49 52 register I32 i_PeRlHaSh = len; \
50 53 register U32 hash_PeRlHaSh = 0; \
51   - while (i_PeRlHaSh--) \
52   - hash_PeRlHaSh = hash_PeRlHaSh * 33 + *s_PeRlHaSh++; \
53   - (hash) = hash_PeRlHaSh + (hash_PeRlHaSh>>5); \
  54 + while (i_PeRlHaSh--) { \
  55 + hash_PeRlHaSh += *s_PeRlHaSh++; \
  56 + hash_PeRlHaSh += (hash_PeRlHaSh << 10); \
  57 + hash_PeRlHaSh ^= (hash_PeRlHaSh >> 6); \
  58 + } \
  59 + hash_PeRlHaSh += (hash_PeRlHaSh << 3); \
  60 + hash_PeRlHaSh ^= (hash_PeRlHaSh >> 11); \
  61 + (hash) = (hash_PeRlHaSh += (hash_PeRlHaSh << 15)); \
54 62 } STMT_END
55 63
56 64 /*
18 pod/perldelta.pod
Source Rendered
@@ -101,6 +101,13 @@ The tr///C and tr///U features have been removed and will not return;
101 101 the interface was a mistake. Sorry about that. For similar
102 102 functionality, see pack('U0', ...) and pack('C0', ...).
103 103
  104 +=item *
  105 +
  106 +Although "you shouldn't do that", it was possible to write code that
  107 +depends on Perl's hashed key order (Data::Dumper does this). The new
  108 +algorithm "One-at-a-Time" produces a different hashed key order.
  109 +More details are in L<perldelta/Performance Enhancements>.
  110 +
104 111 =back
105 112
106 113 =head1 Core Enhancements
@@ -324,6 +331,17 @@ as opposed to quicksort's Theta(N**2) worst-case run time behaviour),
324 331 and that sort() is now stable (meaning that elements with identical
325 332 keys will stay ordered as they were before the sort).
326 333
  334 +=item *
  335 +
  336 +Hashes now use Bob Jenkins "One-at-a-Time" hashing key algorithm
  337 +(http://burtleburtle.net/bob/hash/doobs.html).
  338 +This algorithm is reasonably fast while producing a much better spread
  339 +of values. Hash values output from the algorithm on a hash of all
  340 +3-char printable ASCII keys comes much closer to passing the DIEHARD
  341 +random number generation tests. According to perlbench, this change
  342 +has not affected the overall speed of Perl.
  343 +
  344 +
327 345 =back
328 346
329 347 =head1 Installation and Configuration Improvements
96 t/lib/dumper.t
@@ -87,11 +87,11 @@ $WANT = <<'EOT';
87 87 #$a = [
88 88 # 1,
89 89 # {
90   -# 'a' => $a,
91   -# 'b' => $a->[1],
92 90 # 'c' => [
93 91 # 'c'
94   -# ]
  92 +# ],
  93 +# 'a' => $a,
  94 +# 'b' => $a->[1]
95 95 # },
96 96 # $a->[1]{'c'}
97 97 # ];
@@ -109,11 +109,11 @@ $WANT = <<'EOT';
109 109 #@a = (
110 110 # 1,
111 111 # {
112   -# 'a' => [],
113   -# 'b' => {},
114 112 # 'c' => [
115 113 # 'c'
116   -# ]
  114 +# ],
  115 +# 'a' => [],
  116 +# 'b' => {}
117 117 # },
118 118 # []
119 119 # );
@@ -131,19 +131,19 @@ TEST q(Data::Dumper->Dumpxs([$a, $b], [qw(*a b)])) if $XS;
131 131 ##
132 132 $WANT = <<'EOT';
133 133 #%b = (
  134 +# 'c' => [
  135 +# 'c'
  136 +# ],
134 137 # 'a' => [
135 138 # 1,
136 139 # {},
137   -# [
138   -# 'c'
139   -# ]
  140 +# []
140 141 # ],
141   -# 'b' => {},
142   -# 'c' => []
  142 +# 'b' => {}
143 143 # );
144 144 #$b{'a'}[1] = \%b;
  145 +#$b{'a'}[2] = $b{'c'};
145 146 #$b{'b'} = \%b;
146   -#$b{'c'} = $b{'a'}[2];
147 147 #$a = $b{'a'};
148 148 EOT
149 149
@@ -156,15 +156,15 @@ $WANT = <<'EOT';
156 156 #$a = [
157 157 # 1,
158 158 # {
  159 +# 'c' => [],
159 160 # 'a' => [],
160   -# 'b' => {},
161   -# 'c' => []
  161 +# 'b' => {}
162 162 # },
163 163 # []
164 164 #];
  165 +#$a->[1]{'c'} = \@c;
165 166 #$a->[1]{'a'} = $a;
166 167 #$a->[1]{'b'} = $a->[1];
167   -#$a->[1]{'c'} = \@c;
168 168 #$a->[2] = \@c;
169 169 #$b = $a->[1];
170 170 EOT
@@ -192,12 +192,12 @@ $WANT = <<'EOT';
192 192 # 1,
193 193 # #1
194 194 # {
195   -# a => $a,
196   -# b => $a->[1],
197 195 # c => [
198 196 # #0
199 197 # 'c'
200   -# ]
  198 +# ],
  199 +# a => $a,
  200 +# b => $a->[1]
201 201 # },
202 202 # #2
203 203 # $a->[1]{c}
@@ -217,11 +217,11 @@ $WANT = <<'EOT';
217 217 #$VAR1 = [
218 218 # 1,
219 219 # {
220   -# 'a' => [],
221   -# 'b' => {},
222 220 # 'c' => [
223 221 # 'c'
224   -# ]
  222 +# ],
  223 +# 'a' => [],
  224 +# 'b' => {}
225 225 # },
226 226 # []
227 227 #];
@@ -239,11 +239,11 @@ $WANT = <<'EOT';
239 239 #[
240 240 # 1,
241 241 # {
242   -# a => $VAR1,
243   -# b => $VAR1->[1],
244 242 # c => [
245 243 # 'c'
246   -# ]
  244 +# ],
  245 +# a => $VAR1,
  246 +# b => $VAR1->[1]
247 247 # },
248 248 # $VAR1->[1]{c}
249 249 #]
@@ -262,8 +262,8 @@ EOT
262 262 ##
263 263 $WANT = <<'EOT';
264 264 #$VAR1 = {
265   -# "abc\0'\efg" => "mno\0",
266   -# "reftest" => \\1
  265 +# "reftest" => \\1,
  266 +# "abc\0'\efg" => "mno\0"
267 267 #};
268 268 EOT
269 269
@@ -277,8 +277,8 @@ $foo = { "abc\000\'\efg" => "mno\000",
277 277
278 278 $WANT = <<"EOT";
279 279 #\$VAR1 = {
280   -# 'abc\0\\'\efg' => 'mno\0',
281   -# 'reftest' => \\\\1
  280 +# 'reftest' => \\\\1,
  281 +# 'abc\0\\'\efg' => 'mno\0'
282 282 #};
283 283 EOT
284 284
@@ -313,15 +313,15 @@ EOT
313 313 # do{my $o},
314 314 # #2
315 315 # {
  316 +# 'c' => [],
316 317 # 'a' => 1,
317 318 # 'b' => do{my $o},
318   -# 'c' => [],
319 319 # 'd' => {}
320 320 # }
321 321 # ];
322 322 #*::foo{ARRAY}->[1] = $foo;
323   -#*::foo{ARRAY}->[2]{'b'} = *::foo{SCALAR};
324 323 #*::foo{ARRAY}->[2]{'c'} = *::foo{ARRAY};
  324 +#*::foo{ARRAY}->[2]{'b'} = *::foo{SCALAR};
325 325 #*::foo{ARRAY}->[2]{'d'} = *::foo{ARRAY}->[2];
326 326 #*::foo = *::foo{ARRAY}->[2];
327 327 #@bar = @{*::foo{ARRAY}};
@@ -342,15 +342,15 @@ EOT
342 342 # -10,
343 343 # do{my $o},
344 344 # {
  345 +# 'c' => [],
345 346 # 'a' => 1,
346 347 # 'b' => do{my $o},
347   -# 'c' => [],
348 348 # 'd' => {}
349 349 # }
350 350 #];
351 351 #*::foo{ARRAY}->[1] = $foo;
352   -#*::foo{ARRAY}->[2]{'b'} = *::foo{SCALAR};
353 352 #*::foo{ARRAY}->[2]{'c'} = *::foo{ARRAY};
  353 +#*::foo{ARRAY}->[2]{'b'} = *::foo{SCALAR};
354 354 #*::foo{ARRAY}->[2]{'d'} = *::foo{ARRAY}->[2];
355 355 #*::foo = *::foo{ARRAY}->[2];
356 356 #$bar = *::foo{ARRAY};
@@ -372,13 +372,13 @@ EOT
372 372 #*::foo = \5;
373 373 #*::foo = \@bar;
374 374 #*::foo = {
  375 +# 'c' => [],
375 376 # 'a' => 1,
376 377 # 'b' => do{my $o},
377   -# 'c' => [],
378 378 # 'd' => {}
379 379 #};
380   -#*::foo{HASH}->{'b'} = *::foo{SCALAR};
381 380 #*::foo{HASH}->{'c'} = \@bar;
  381 +#*::foo{HASH}->{'b'} = *::foo{SCALAR};
382 382 #*::foo{HASH}->{'d'} = *::foo{HASH};
383 383 #$bar[2] = *::foo{HASH};
384 384 #%baz = %{*::foo{HASH}};
@@ -399,13 +399,13 @@ EOT
399 399 #*::foo = \5;
400 400 #*::foo = $bar;
401 401 #*::foo = {
  402 +# 'c' => [],
402 403 # 'a' => 1,
403 404 # 'b' => do{my $o},
404   -# 'c' => [],
405 405 # 'd' => {}
406 406 #};
407   -#*::foo{HASH}->{'b'} = *::foo{SCALAR};
408 407 #*::foo{HASH}->{'c'} = $bar;
  408 +#*::foo{HASH}->{'b'} = *::foo{SCALAR};
409 409 #*::foo{HASH}->{'d'} = *::foo{HASH};
410 410 #$bar->[2] = *::foo{HASH};
411 411 #$baz = *::foo{HASH};
@@ -423,9 +423,9 @@ EOT
423 423 # -10,
424 424 # $foo,
425 425 # {
  426 +# c => \@bar,
426 427 # a => 1,
427 428 # b => \5,
428   -# c => \@bar,
429 429 # d => $bar[2]
430 430 # }
431 431 #);
@@ -445,9 +445,9 @@ EOT
445 445 # -10,
446 446 # $foo,
447 447 # {
  448 +# c => $bar,
448 449 # a => 1,
449 450 # b => \5,
450   -# c => $bar,
451 451 # d => $bar->[2]
452 452 # }
453 453 #];
@@ -476,8 +476,8 @@ EOT
476 476 ##
477 477 $WANT = <<'EOT';
478 478 #%kennels = (
479   -# First => \'Fido',
480   -# Second => \'Wags'
  479 +# Second => \'Wags',
  480 +# First => \'Fido'
481 481 #);
482 482 #@dogs = (
483 483 # ${$kennels{First}},
@@ -515,8 +515,8 @@ EOT
515 515 ##
516 516 $WANT = <<'EOT';
517 517 #%kennels = (
518   -# First => \'Fido',
519   -# Second => \'Wags'
  518 +# Second => \'Wags',
  519 +# First => \'Fido'
520 520 #);
521 521 #@dogs = (
522 522 # ${$kennels{First}},
@@ -539,8 +539,8 @@ EOT
539 539 # 'Fido',
540 540 # 'Wags',
541 541 # {
542   -# First => \$dogs[0],
543   -# Second => \$dogs[1]
  542 +# Second => \$dogs[1],
  543 +# First => \$dogs[0]
544 544 # }
545 545 #);
546 546 #%kennels = %{$dogs[2]};
@@ -574,13 +574,13 @@ EOT
574 574 # 'Fido',
575 575 # 'Wags',
576 576 # {
577   -# First => \'Fido',
578   -# Second => \'Wags'
  577 +# Second => \'Wags',
  578 +# First => \'Fido'
579 579 # }
580 580 #);
581 581 #%kennels = (
582   -# First => \'Fido',
583   -# Second => \'Wags'
  582 +# Second => \'Wags',
  583 +# First => \'Fido'
584 584 #);
585 585 EOT
586 586
2  t/pragma/warn/perl
@@ -46,8 +46,8 @@ $x = 3 ;
46 46 use warnings 'once' ;
47 47 $z = 3 ;
48 48 EXPECT
49   -Name "main::x" used only once: possible typo at - line 4.
50 49 Name "main::z" used only once: possible typo at - line 6.
  50 +Name "main::x" used only once: possible typo at - line 4.
51 51 ########
52 52 -X
53 53 # perl.c

0 comments on commit a6fe520

Please sign in to comment.
Something went wrong with that request. Please try again.