]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/doc/xml/manual/test_policy_data_structures.xml
build_hacking.xml: Use relative fileref for PNG imagedata.
[thirdparty/gcc.git] / libstdc++-v3 / doc / xml / manual / test_policy_data_structures.xml
1 <section xmlns="http://docbook.org/ns/docbook" version="5.0"
2 xml:id="pbds.test" xreflabel="Test">
3 <info><title>Testing</title></info>
4 <?dbhtml filename="policy_based_data_structures_test.html"?>
5
6 <!-- S01 regression -->
7 <section xml:id="pbds.test.regression">
8 <info><title>Regression</title></info>
9
10 <para>The library contains a single comprehensive regression test.
11 For a given container type in this library, the test creates
12 an object of the container type and an object of the
13 corresponding standard type (e.g., <classname>std::set</classname>). It
14 then performs a random sequence of methods with random
15 arguments (e.g., inserts, erases, and so forth) on both
16 objects. At each operation, the test checks the return value of
17 the method, and optionally both compares this library's
18 object with the standard's object as well as performing other
19 consistency checks on this library's object (e.g.,
20 order preservation, when applicable, or node invariants, when
21 applicable).</para>
22
23 <para>Additionally, the test integrally checks exception safety
24 and resource leaks. This is done as follows. A special
25 allocator type, written for the purpose of the test, both
26 randomly throws an exceptions when allocations are performed,
27 and tracks allocations and de-allocations. The exceptions thrown
28 at allocations simulate memory-allocation failures; the
29 tracking mechanism checks for memory-related bugs (e.g.,
30 resource leaks and multiple de-allocations). Both
31 this library's containers and the containers' value-types are
32 configured to use this allocator.</para>
33
34 <para>For granularity, the test is split into the
35 several sources, each checking only some containers.</para>
36
37 <para>For more details, consult the files in
38 <filename>testsuite/ext/pb_ds/regression</filename>.</para>
39 </section>
40
41 <!-- S02 performance -->
42 <section xml:id="pbds.test.performance">
43 <info><title>Performance</title></info>
44
45 <section xml:id="performance.hash">
46 <info><title>Hash-Based</title></info>
47 <para></para>
48
49 <!-- 01 <a href="hash_text_find_find_timing_test"> -->
50 <section xml:id="performance.hash.text_find">
51 <info><title>
52 Text <function>find</function>
53 </title></info>
54 <para></para>
55
56 <section xml:id="hash.text_find.info">
57 <info><title>
58 Description
59 </title></info>
60
61 <para>
62 This test inserts a number of values with keys from an
63 arbitrary text (<xref
64 linkend="biblio.wickland96thirty"/>) into a container,
65 then performs a series of finds using
66 <function>find</function> . It measures the average
67 time for <function>find</function> as a function of
68 the number of values inserted.</para>
69 <para>
70 It uses the test file:
71 <filename>
72 performance/ext/pb_ds/text_find_timing_test.cc
73 </filename>
74 </para>
75
76 <para>
77 And uses the data file:
78 <filename>
79 filethirty_years_among_the_dead_preproc.txt
80 </filename>
81 </para>
82
83 <para>The test checks the effect of different range-hashing
84 functions, trigger policies, and cache-hashing policies.
85 </para>
86
87 </section>
88
89 <section xml:id="hash.text_find.results">
90 <info><title>
91 Results
92 </title></info>
93
94 <para>The graphic below show the results for the native
95 and collision-chaining hash types the the function
96 applied being a text find timing test using
97 <function>find</function>.
98 </para>
99
100 <!-- results graphic -->
101 <informalfigure>
102 <mediaobject>
103 <imageobject>
104 <imagedata align="center" format="PDF" scale="75"
105 fileref="../images/pbds_text_find_timing_test_hash_local.pdf"/>
106 </imageobject>
107 <imageobject>
108 <imagedata align="center" format="PNG" scale="100"
109 fileref="../images/pbds_text_find_timing_test_hash_local.png"/>
110 </imageobject>
111 </mediaobject>
112 </informalfigure>
113
114 <para>
115 The abbreviated names in the legend of the graphic above are
116 instantiated with the types in the following table.
117 </para>
118
119
120 <informaltable frame="all">
121
122 <tgroup cols="5" align="left" colsep="1" rowsep="1">
123 <colspec colname="c1"/>
124 <colspec colname="c2"/>
125 <colspec colname="c3"/>
126 <colspec colname="c4"/>
127 <colspec colname="c5"/>
128 <thead>
129 <row>
130 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
131 <entry><emphasis>Parameter</emphasis></entry>
132 <entry><emphasis>Details</emphasis></entry>
133 <entry><emphasis>Parameter</emphasis></entry>
134 <entry><emphasis>Details</emphasis></entry>
135 </row>
136 </thead>
137
138 <tbody>
139
140 <!-- native -->
141 <row>
142 <?dbhtml bgcolor="#B0B0B0" ?>
143 <entry namest="c1" nameend="c5">
144 n_hash_map_ncah
145 </entry>
146 </row>
147
148 <row>
149 <entry>
150 <classname>std::tr1::unordered_map</classname>
151 </entry>
152 <entry>
153 <classname>cache_hash_code</classname>
154 </entry>
155 <entry>
156 <constant>false</constant>
157 </entry>
158 <entry namest="c4" nameend="c5"></entry>
159 </row>
160
161 <!-- hash 01 -->
162 <row>
163 <?dbhtml bgcolor="#B0B0B0" ?>
164 <entry namest="c1" nameend="c5">
165 cc_hash_mod_prime_nea_lc_1div8_1div1_nsth_map
166 </entry>
167 </row>
168
169 <row>
170 <entry morerows="2" valign="top">
171 <classname>cc_hash_table</classname>
172 </entry>
173 <entry>
174 <classname>Comb_Hash_Fn</classname>
175 </entry>
176 <entry>
177 <classname>direct_mod_range_hashing</classname>
178 </entry>
179 <entry namest="c4" nameend="c5"></entry>
180 </row>
181
182 <row>
183 <entry morerows="1" valign="top">
184 <classname>Resize_Policy</classname>
185 </entry>
186 <entry morerows="1" valign="top">
187 <classname>hash_standard_resize_policy</classname>
188 </entry>
189 <entry>
190 <classname>Size_Policy</classname>
191 </entry>
192 <entry>
193 <classname>hash_prime_size_policy</classname>
194 </entry>
195 </row>
196
197 <row>
198 <entry valign="top">
199 <classname>Trigger_Policy</classname>
200 </entry>
201 <entry>
202 <classname>hash_load_check_resize_trigger</classname> with
203 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/1
204 </entry>
205 </row>
206
207 <!-- hash 02 -->
208 <row>
209 <?dbhtml bgcolor="#B0B0B0" ?>
210 <entry namest="c1" nameend="c5">
211 cc_hash_mask_exp_nea_lc_1div8_1div2_sth_map
212 </entry>
213 </row>
214
215 <row>
216 <entry morerows="2" valign="top">
217 <classname>
218 cc_hash_table
219 </classname>
220 </entry>
221 <entry>
222 <classname>Comb_Hash_Fn</classname>
223 </entry>
224 <entry>
225 <classname>direct_mask_range_hashing</classname>
226 </entry>
227 <entry namest="c4" nameend="c5"></entry>
228 </row>
229
230 <row>
231 <entry morerows="1" valign="top">
232 <classname>Resize_Policy</classname>
233 </entry>
234 <entry morerows="1" valign="top">
235 <classname>hash_standard_resize_policy</classname>
236 </entry>
237 <entry>
238 <classname>Size_Policy</classname>
239 </entry>
240 <entry>
241 <classname>hash_exponential_size_policy</classname>
242 </entry>
243 </row>
244
245 <row>
246 <entry valign="top">
247 <classname>Trigger_Policy</classname>
248 </entry>
249 <entry>
250 <classname>hash_load_check_resize_trigger</classname> with
251 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
252 </entry>
253 </row>
254
255 <!-- hash 03 -->
256 <row>
257 <?dbhtml bgcolor="#B0B0B0" ?>
258 <entry namest="c1" nameend="c5">
259 cc_hash_mask_exp_nea_lc_1div8_1div1_nsth_map
260 </entry>
261 </row>
262
263 <row>
264 <entry morerows="2" valign="top">
265 <classname>cc_hash_table</classname>
266 </entry>
267 <entry>
268 <classname>Comb_Hash_Fn</classname>
269 </entry>
270 <entry>
271 <classname>direct_mask_range_hashing</classname>
272 </entry>
273 <entry namest="c4" nameend="c5"></entry>
274 </row>
275
276 <row>
277 <entry morerows="1" valign="top">
278 <classname>Resize_Policy</classname>
279 </entry>
280 <entry morerows="1" valign="top">
281 <classname>hash_standard_resize_policy</classname>
282 </entry>
283 <entry>
284 <classname>Size_Policy</classname>
285 </entry>
286 <entry>
287 <classname>hash_exponential_size_policy</classname>
288 </entry>
289 </row>
290
291 <row>
292 <entry valign="top">
293 <classname>Trigger_Policy</classname>
294 </entry>
295 <entry>
296 <classname>hash_load_check_resize_trigger</classname> with
297 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/1
298 </entry>
299 </row>
300
301 <!-- hash 04 -->
302 <row>
303 <?dbhtml bgcolor="#B0B0B0" ?>
304 <entry namest="c1" nameend="c5">
305 cc_hash_mask_exp_nea_lc_1div8_1div2_nsth_map
306 </entry>
307 </row>
308 <row>
309 <entry morerows="2" valign="top">
310 <classname>cc_hash_table</classname>
311 </entry>
312 <entry>
313 <classname>Comb_Hash_Fn</classname>
314 </entry>
315 <entry>
316 <classname>direct_mask_range_hashing</classname>
317 </entry>
318 <entry namest="c4" nameend="c5"></entry>
319 </row>
320
321 <row>
322 <entry morerows="1" valign="top">
323 <classname>Resize_Policy</classname>
324 </entry>
325 <entry morerows="1" valign="top">
326 <classname>hash_standard_resize_policy</classname>
327 </entry>
328 <entry>
329 <classname>Size_Policy</classname>
330 </entry>
331 <entry>
332 <classname>hash_exponential_size_policy</classname>
333 </entry>
334 </row>
335
336 <row>
337 <entry valign="top">
338 <classname>Trigger_Policy</classname>
339 </entry>
340 <entry>
341 <classname>hash_load_check_resize_trigger</classname> with
342 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
343 </entry>
344 </row>
345
346 </tbody>
347 </tgroup>
348 </informaltable>
349
350 </section>
351
352 <section xml:id="hash.text_find.observations">
353 <info><title>
354 Observations
355 </title></info>
356
357 <para>In this setting, the range-hashing scheme affects performance
358 more than other policies. As the results show, containers using
359 mod-based range-hashing (including the native hash-based container,
360 which is currently hard-wired to this scheme) have lower performance
361 than those using mask-based range-hashing. A modulo-based
362 range-hashing scheme's main benefit is that it takes into account
363 all hash-value bits. Standard string hash-functions are designed to
364 create hash values that are nearly-uniform as is (<xref
365 linkend="biblio.knuth98sorting"/>).</para>
366
367 <para>Trigger policies, i.e. the load-checks constants, affect
368 performance to a lesser extent.</para>
369
370 <para>Perhaps surprisingly, storing the hash value alongside each
371 entry affects performance only marginally, at least in this
372 library's implementation. (Unfortunately, it was not possible to run
373 the tests with <classname>std::tr1::unordered_map</classname> 's
374 <classname>cache_hash_code = true</classname> , as it appeared to
375 malfuntion.)</para>
376
377 </section>
378
379 </section>
380
381 <!-- 02 <a href="hash_int_find_timing_test"> -->
382 <section xml:id="performance.hash.int_find">
383 <info><title>
384 Integer <function>find</function>
385 </title></info>
386 <para></para>
387
388 <section xml:id="hash.int_find.info">
389 <info><title>
390 Description
391 </title></info>
392
393 <para>This test inserts a number of values with uniform
394 integer keys into a container, then performs a series of finds
395 using <function>find</function>. It measures the average time
396 for <function>find</function> as a function of the number of values
397 inserted.</para>
398
399 <para>
400 It uses the test file:
401 <filename>
402 performance/ext/pb_ds/random_int_find_timing.cc
403 </filename>
404 </para>
405
406 <para>The test checks the effect of different underlying
407 hash-tables,
408 range-hashing functions, and trigger policies.</para>
409
410 </section>
411
412 <section xml:id="hash.int_find.results">
413 <info><title>
414 Results
415 </title></info>
416
417 <para>
418 There are two sets of results for this type, one for
419 collision-chaining hashes, and one for general-probe hashes.
420 </para>
421
422 <para>The first graphic below shows the results for the native and
423 collision-chaining hash types. The function applied being a random
424 integer timing test using <function>find</function>.
425 </para>
426
427 <!-- results graphic 01 -->
428 <informalfigure>
429 <mediaobject>
430 <imageobject>
431 <imagedata align="center" format="PDF" scale="75"
432 fileref="../images/pbds_cc_hash_random_int_find_timing_test_local.pdf"/>
433 </imageobject>
434 <imageobject>
435 <imagedata align="center" format="PNG" scale="100"
436 fileref="../images/pbds_cc_hash_random_int_find_timing_test_local.png"/>
437 </imageobject>
438 </mediaobject>
439 </informalfigure>
440
441 <para>
442 The abbreviated names in the legend of the graphic above are
443 instantiated with the types in the following table.
444 </para>
445
446
447 <informaltable frame="all">
448
449 <tgroup cols="5" align="left" colsep="1" rowsep="1">
450 <colspec colname="c1"/>
451 <colspec colname="c2"/>
452 <colspec colname="c3"/>
453 <colspec colname="c4"/>
454 <colspec colname="c5"/>
455 <thead>
456 <row>
457 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
458 <entry><emphasis>Parameter</emphasis></entry>
459 <entry><emphasis>Details</emphasis></entry>
460 <entry><emphasis>Parameter</emphasis></entry>
461 <entry><emphasis>Details</emphasis></entry>
462 </row>
463 </thead>
464
465 <tbody>
466
467 <!-- native -->
468 <row>
469 <?dbhtml bgcolor="#B0B0B0" ?>
470 <entry namest="c1" nameend="c5">
471 n_hash_map_ncah
472 </entry>
473 </row>
474
475 <row>
476 <entry>
477 <classname>std::tr1::unordered_map</classname>
478 </entry>
479 <entry>
480 <classname>cache_hash_code</classname>
481 </entry>
482 <entry>
483 <constant>false</constant>
484 </entry>
485 <entry namest="c4" nameend="c5"></entry>
486 </row>
487
488 <!-- hash 01 -->
489 <row>
490 <?dbhtml bgcolor="#B0B0B0" ?>
491 <entry namest="c1" nameend="c5">
492 cc_hash_mod_prime_nea_lc_1div8_1div1_nsth_map
493 </entry>
494 </row>
495
496 <row>
497 <entry morerows="2" valign="top">
498 <classname>cc_hash_table</classname>
499 </entry>
500 <entry>
501 <classname>Comb_Hash_Fn</classname>
502 </entry>
503 <entry>
504 <classname>direct_mod_range_hashing</classname>
505 </entry>
506 <entry namest="c4" nameend="c5"></entry>
507 </row>
508
509 <row>
510 <entry morerows="1" valign="top">
511 <classname>Resize_Policy</classname>
512 </entry>
513 <entry morerows="1" valign="top">
514 <classname>hash_standard_resize_policy</classname>
515 </entry>
516 <entry>
517 <classname>Size_Policy</classname>
518 </entry>
519 <entry>
520 <classname>hash_prime_size_policy</classname>
521 </entry>
522 </row>
523
524 <row>
525 <entry valign="top">
526 <classname>Trigger_Policy</classname>
527 </entry>
528 <entry>
529 <classname>hash_load_check_resize_trigger</classname> with
530 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/1
531 </entry>
532 </row>
533
534 <!-- hash 02 -->
535 <row>
536 <?dbhtml bgcolor="#B0B0B0" ?>
537 <entry namest="c1" nameend="c5">
538 cc_hash_mod_prime_nea_lc_1div8_1div2_nsth_map
539 </entry>
540 </row>
541
542 <row>
543 <entry morerows="2" valign="top">
544 <classname>
545 cc_hash_table
546 </classname>
547 </entry>
548 <entry>
549 <classname>Comb_Hash_Fn</classname>
550 </entry>
551 <entry>
552 <classname>direct_mod_range_hashing</classname>
553 </entry>
554 <entry namest="c4" nameend="c5"></entry>
555 </row>
556
557 <row>
558 <entry morerows="1" valign="top">
559 <classname>Resize_Policy</classname>
560 </entry>
561 <entry morerows="1" valign="top">
562 <classname>hash_standard_resize_policy</classname>
563 </entry>
564 <entry>
565 <classname>Size_Policy</classname>
566 </entry>
567 <entry>
568 <classname>hash_prime_size_policy</classname>
569 </entry>
570 </row>
571
572 <row>
573 <entry valign="top">
574 <classname>Trigger_Policy</classname>
575 </entry>
576 <entry>
577 <classname>hash_load_check_resize_trigger</classname> with
578 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
579 </entry>
580 </row>
581
582 <!-- hash 03 -->
583 <row>
584 <?dbhtml bgcolor="#B0B0B0" ?>
585 <entry namest="c1" nameend="c5">
586 cc_hash_mask_exp_nea_lc_1div8_1div1_nsth_map
587 </entry>
588 </row>
589
590 <row>
591 <entry morerows="2" valign="top">
592 <classname>cc_hash_table</classname>
593 </entry>
594 <entry>
595 <classname>Comb_Hash_Fn</classname>
596 </entry>
597 <entry>
598 <classname>direct_mask_range_hashing</classname>
599 </entry>
600 <entry namest="c4" nameend="c5"></entry>
601 </row>
602
603 <row>
604 <entry morerows="1" valign="top">
605 <classname>Resize_Policy</classname>
606 </entry>
607 <entry morerows="1" valign="top">
608 <classname>hash_standard_resize_policy</classname>
609 </entry>
610 <entry>
611 <classname>Size_Policy</classname>
612 </entry>
613 <entry>
614 <classname>hash_exponential_size_policy</classname>
615 </entry>
616 </row>
617
618 <row>
619 <entry valign="top">
620 <classname>Trigger_Policy</classname>
621 </entry>
622 <entry>
623 <classname>hash_load_check_resize_trigger</classname> with
624 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/1
625 </entry>
626 </row>
627
628 <!-- hash 04 -->
629 <row>
630 <?dbhtml bgcolor="#B0B0B0" ?>
631 <entry namest="c1" nameend="c5">
632 cc_hash_mask_exp_nea_lc_1div8_1div2_nsth_map
633 </entry>
634 </row>
635 <row>
636 <entry morerows="2" valign="top">
637 <classname>cc_hash_table</classname>
638 </entry>
639 <entry>
640 <classname>Comb_Hash_Fn</classname>
641 </entry>
642 <entry>
643 <classname>direct_mask_range_hashing</classname>
644 </entry>
645 <entry namest="c4" nameend="c5"></entry>
646 </row>
647
648 <row>
649 <entry morerows="1" valign="top">
650 <classname>Resize_Policy</classname>
651 </entry>
652 <entry morerows="1" valign="top">
653 <classname>hash_standard_resize_policy</classname>
654 </entry>
655 <entry>
656 <classname>Size_Policy</classname>
657 </entry>
658 <entry>
659 <classname>hash_exponential_size_policy</classname>
660 </entry>
661 </row>
662
663 <row>
664 <entry valign="top">
665 <classname>Trigger_Policy</classname>
666 </entry>
667 <entry>
668 <classname>hash_load_check_resize_trigger</classname> with
669 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
670 </entry>
671 </row>
672
673 </tbody>
674 </tgroup>
675 </informaltable>
676
677 <para>
678 </para>
679
680 <para>
681 </para>
682
683 <para>And the second graphic shows the results for the native and
684 general-probe hash types. The function applied being a random
685 integer timing test using <function>find</function>.
686 </para>
687
688 <!-- results graphic 02 -->
689 <informalfigure>
690 <mediaobject>
691 <imageobject>
692 <imagedata align="center" format="PDF" scale="75"
693 fileref="../images/pbds_gp_hash_random_int_find_timing_test_local.pdf"/>
694 </imageobject>
695 <imageobject>
696 <imagedata align="center" format="PNG" scale="100"
697 fileref="../images/pbds_gp_hash_random_int_find_timing_test_local.png"/>
698 </imageobject>
699 </mediaobject>
700 </informalfigure>
701
702 <para>
703 The abbreviated names in the legend of the graphic above are
704 instantiated with the types in the following table.
705 </para>
706
707
708 <informaltable frame="all">
709
710 <tgroup cols="5" align="left" colsep="1" rowsep="1">
711 <colspec colname="c1"/>
712 <colspec colname="c2"/>
713 <colspec colname="c3"/>
714 <colspec colname="c4"/>
715 <colspec colname="c5"/>
716 <thead>
717 <row>
718 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
719 <entry><emphasis>Parameter</emphasis></entry>
720 <entry><emphasis>Details</emphasis></entry>
721 <entry><emphasis>Parameter</emphasis></entry>
722 <entry><emphasis>Details</emphasis></entry>
723 </row>
724 </thead>
725
726 <tbody>
727
728 <!-- native -->
729 <row>
730 <?dbhtml bgcolor="#B0B0B0" ?>
731 <entry namest="c1" nameend="c5">
732 n_hash_map_ncah
733 </entry>
734 </row>
735
736 <row>
737 <entry>
738 <classname>std::tr1::unordered_map</classname>
739 </entry>
740 <entry>
741 <classname>cache_hash_code</classname>
742 </entry>
743 <entry>
744 <constant>false</constant>
745 </entry>
746 <entry namest="c4" nameend="c5"></entry>
747 </row>
748
749 <!-- hash 01 -->
750 <row>
751 <?dbhtml bgcolor="#B0B0B0" ?>
752 <entry namest="c1" nameend="c5">
753 gp_hash_mod_quadp_prime_nea_lc_1div8_1div2_nsth_map
754 </entry>
755 </row>
756
757 <row>
758 <entry morerows="3" valign="top">
759 <classname>gp_hash_table</classname>
760 </entry>
761 <entry>
762 <classname>Comb_Hash_Fn</classname>
763 </entry>
764 <entry>
765 <classname>direct_mod_range_hashing</classname>
766 </entry>
767 <entry namest="c4" nameend="c5"></entry>
768 </row>
769
770 <row>
771 <entry>
772 <classname>Probe_Fn</classname>
773 </entry>
774 <entry>
775 <classname>quadratic_probe_fn</classname>
776 </entry>
777 <entry namest="c4" nameend="c5"></entry>
778 </row>
779
780 <row>
781 <entry morerows="1" valign="top">
782 <classname>Resize_Policy</classname>
783 </entry>
784 <entry morerows="1" valign="top">
785 <classname>hash_standard_resize_policy</classname>
786 </entry>
787 <entry>
788 <classname>Size_Policy</classname>
789 </entry>
790 <entry>
791 <classname>hash_prime_size_policy</classname>
792 </entry>
793 </row>
794
795 <row>
796 <entry valign="top">
797 <classname>Trigger_Policy</classname>
798 </entry>
799 <entry>
800 <classname>hash_load_check_resize_trigger</classname> with
801 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
802 </entry>
803 </row>
804
805 <!-- hash 02 -->
806 <row>
807 <?dbhtml bgcolor="#B0B0B0" ?>
808 <entry namest="c1" nameend="c5">
809 gp_hash_mask_linp_exp_nea_lc_1div8_1div2_nsth_map
810 </entry>
811 </row>
812
813 <row>
814 <entry morerows="3" valign="top">
815 <classname>
816 gp_hash_table
817 </classname>
818 </entry>
819 <entry>
820 <classname>Comb_Hash_Fn</classname>
821 </entry>
822 <entry>
823 <classname>direct_mask_range_hashing</classname>
824 </entry>
825 <entry namest="c4" nameend="c5"></entry>
826 </row>
827
828 <row>
829 <entry>
830 <classname>Probe_Fn</classname>
831 </entry>
832 <entry>
833 <classname>linear_probe_fn</classname>
834 </entry>
835 <entry namest="c4" nameend="c5"></entry>
836 </row>
837
838 <row>
839 <entry morerows="1" valign="top">
840 <classname>Resize_Policy</classname>
841 </entry>
842 <entry morerows="1" valign="top">
843 <classname>hash_standard_resize_policy</classname>
844 </entry>
845 <entry>
846 <classname>Size_Policy</classname>
847 </entry>
848 <entry>
849 <classname>hash_exponential_size_policy</classname>
850 </entry>
851 </row>
852
853 <row>
854 <entry valign="top">
855 <classname>Trigger_Policy</classname>
856 </entry>
857 <entry>
858 <classname>hash_load_check_resize_trigger</classname> with
859 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
860 </entry>
861 </row>
862
863 </tbody>
864 </tgroup>
865 </informaltable>
866
867 </section>
868
869 <section xml:id="hash.int_find.observations">
870 <info><title>
871 Observations
872 </title></info>
873
874 <para>In this setting, the choice of underlying hash-table affects
875 performance most, then the range-hashing scheme and, only finally,
876 other policies.</para>
877
878 <para>When comparing probing and chaining containers, it is
879 apparent that the probing containers are less efficient than the
880 collision-chaining containers (
881 <classname>std::tr1::unordered_map</classname> uses
882 collision-chaining) in this case.</para>
883
884 <para>Hash-Based Integer Subscript Insert Timing Test shows
885 a different case, where the situation is reversed;
886 </para>
887
888 <para>Within each type of hash-table, the range-hashing scheme
889 affects performance more than other policies; Hash-Based Text
890 <function>find</function> Find Timing Test also shows this. In the
891 above graphics should be noted that
892 <classname>std::tr1::unordered_map</classname> are hard-wired
893 currently to mod-based schemes.
894 </para>
895
896 </section>
897
898 </section>
899
900 <!-- 03 <a href="hash_int_subscript_find_test"> -->
901 <section xml:id="performance.hash.int_subscript_find">
902 <info><title>
903 Integer Subscript <function>find</function>
904 </title></info>
905 <para></para>
906
907 <section xml:id="hash.int_subscript_find.info">
908 <info><title>
909 Description
910 </title></info>
911
912 <para>This test inserts a number of values with uniform
913 integer keys into a container, then performs a series of finds
914 using <function>operator[]</function>. It measures the average time
915 for <function>operator[]</function> as a function of the number of
916 values inserted.</para>
917
918 <para>
919 It uses the test file:
920 <filename>
921 performance/ext/pb_ds/random_int_subscript_find_timing.cc
922 </filename>
923 </para>
924
925 <para>The test checks the effect of different underlying
926 hash-tables, range-hashing functions, and trigger policies.</para>
927
928
929 </section>
930
931 <section xml:id="hash.int_subscript_find.results">
932 <info><title>
933 Results
934 </title></info>
935
936 <para>
937 There are two sets of results for this type, one for
938 collision-chaining hashes, and one for general-probe hashes.
939 </para>
940
941 <para>The first graphic below shows the results for the native
942 and collision-chaining hash types, using as the function
943 applied an integer subscript timing test with
944 <function>find</function>.
945 </para>
946
947 <!-- results graphic -->
948 <informalfigure>
949 <mediaobject>
950 <imageobject>
951 <imagedata align="center" format="PDF" scale="75"
952 fileref="../images/pbds_cc_hash_random_int_subscript_timing_test_find_local.pdf"/>
953 </imageobject>
954 <imageobject>
955 <imagedata align="center" format="PNG" scale="100"
956 fileref="../images/pbds_cc_hash_random_int_subscript_timing_test_find_local.png"/>
957 </imageobject>
958 </mediaobject>
959 </informalfigure>
960
961 <para>
962 The abbreviated names in the legend of the graphic above are
963 instantiated with the types in the following table.
964 </para>
965
966 <informaltable frame="all">
967
968 <tgroup cols="5" align="left" colsep="1" rowsep="1">
969 <colspec colname="c1"/>
970 <colspec colname="c2"/>
971 <colspec colname="c3"/>
972 <colspec colname="c4"/>
973 <colspec colname="c5"/>
974 <thead>
975 <row>
976 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
977 <entry><emphasis>Parameter</emphasis></entry>
978 <entry><emphasis>Details</emphasis></entry>
979 <entry><emphasis>Parameter</emphasis></entry>
980 <entry><emphasis>Details</emphasis></entry>
981 </row>
982 </thead>
983
984 <tbody>
985
986 <!-- native -->
987 <row>
988 <?dbhtml bgcolor="#B0B0B0" ?>
989 <entry namest="c1" nameend="c5">
990 n_hash_map_ncah
991 </entry>
992 </row>
993
994 <row>
995 <entry>
996 <classname>std::tr1::unordered_map</classname>
997 </entry>
998 <entry>
999 <classname>cache_hash_code</classname>
1000 </entry>
1001 <entry>
1002 <constant>false</constant>
1003 </entry>
1004 <entry namest="c4" nameend="c5"></entry>
1005 </row>
1006
1007 <!-- hash 01 -->
1008 <row>
1009 <?dbhtml bgcolor="#B0B0B0" ?>
1010 <entry namest="c1" nameend="c5">
1011 cc_hash_mod_prime_nea_lc_1div8_1div1_nsth_map
1012 </entry>
1013 </row>
1014
1015 <row>
1016 <entry morerows="2" valign="top">
1017 <classname>cc_hash_table</classname>
1018 </entry>
1019 <entry>
1020 <classname>Comb_Hash_Fn</classname>
1021 </entry>
1022 <entry>
1023 <classname>direct_mod_range_hashing</classname>
1024 </entry>
1025 <entry namest="c4" nameend="c5"></entry>
1026 </row>
1027
1028 <row>
1029 <entry morerows="1" valign="top">
1030 <classname>Resize_Policy</classname>
1031 </entry>
1032 <entry morerows="1" valign="top">
1033 <classname>hash_standard_resize_policy</classname>
1034 </entry>
1035 <entry>
1036 <classname>Size_Policy</classname>
1037 </entry>
1038 <entry>
1039 <classname>hash_prime_size_policy</classname>
1040 </entry>
1041 </row>
1042
1043 <row>
1044 <entry valign="top">
1045 <classname>Trigger_Policy</classname>
1046 </entry>
1047 <entry>
1048 <classname>hash_load_check_resize_trigger</classname> with
1049 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/1
1050 </entry>
1051 </row>
1052
1053 <!-- hash 02 -->
1054 <row>
1055 <?dbhtml bgcolor="#B0B0B0" ?>
1056 <entry namest="c1" nameend="c5">
1057 cc_hash_mod_prime_nea_lc_1div8_1div2_nsth_map
1058 </entry>
1059 </row>
1060
1061 <row>
1062 <entry morerows="2" valign="top">
1063 <classname>cc_hash_table</classname>
1064 </entry>
1065 <entry>
1066 <classname>Comb_Hash_Fn</classname>
1067 </entry>
1068 <entry>
1069 <classname>direct_mod_range_hashing</classname>
1070 </entry>
1071 <entry namest="c4" nameend="c5"></entry>
1072 </row>
1073
1074 <row>
1075 <entry morerows="1" valign="top">
1076 <classname>Resize_Policy</classname>
1077 </entry>
1078 <entry morerows="1" valign="top">
1079 <classname>hash_standard_resize_policy</classname>
1080 </entry>
1081 <entry>
1082 <classname>Size_Policy</classname>
1083 </entry>
1084 <entry>
1085 <classname>hash_prime_size_policy</classname>
1086 </entry>
1087 </row>
1088
1089 <row>
1090 <entry valign="top">
1091 <classname>Trigger_Policy</classname>
1092 </entry>
1093 <entry>
1094 <classname>hash_load_check_resize_trigger</classname> with
1095 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
1096 </entry>
1097 </row>
1098
1099 <!-- hash 03 -->
1100 <row>
1101 <?dbhtml bgcolor="#B0B0B0" ?>
1102 <entry namest="c1" nameend="c5">
1103 cc_hash_mask_exp_nea_lc_1div8_1div1_nsth_map
1104 </entry>
1105 </row>
1106
1107 <row>
1108 <entry morerows="2" valign="top">
1109 <classname>cc_hash_table</classname>
1110 </entry>
1111 <entry>
1112 <classname>Comb_Hash_Fn</classname>
1113 </entry>
1114 <entry>
1115 <classname>direct_mask_range_hashing</classname>
1116 </entry>
1117 <entry namest="c4" nameend="c5"></entry>
1118 </row>
1119
1120 <row>
1121 <entry morerows="1" valign="top">
1122 <classname>Resize_Policy</classname>
1123 </entry>
1124 <entry morerows="1" valign="top">
1125 <classname>hash_standard_resize_policy</classname>
1126 </entry>
1127 <entry>
1128 <classname>Size_Policy</classname>
1129 </entry>
1130 <entry>
1131 <classname>hash_exponential_size_policy</classname>
1132 </entry>
1133 </row>
1134
1135 <row>
1136 <entry valign="top">
1137 <classname>Trigger_Policy</classname>
1138 </entry>
1139 <entry>
1140 <classname>hash_load_check_resize_trigger</classname> with
1141 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/1
1142 </entry>
1143 </row>
1144
1145 <!-- hash 04 -->
1146 <row>
1147 <?dbhtml bgcolor="#B0B0B0" ?>
1148 <entry namest="c1" nameend="c5">
1149 cc_hash_mask_exp_nea_lc_1div8_1div2_nsth_map
1150 </entry>
1151 </row>
1152 <row>
1153 <entry morerows="2" valign="top">
1154 <classname>cc_hash_table</classname>
1155 </entry>
1156 <entry>
1157 <classname>Comb_Hash_Fn</classname>
1158 </entry>
1159 <entry>
1160 <classname>direct_mask_range_hashing</classname>
1161 </entry>
1162 <entry namest="c4" nameend="c5"></entry>
1163 </row>
1164
1165 <row>
1166 <entry morerows="1" valign="top">
1167 <classname>Resize_Policy</classname>
1168 </entry>
1169 <entry morerows="1" valign="top">
1170 <classname>hash_standard_resize_policy</classname>
1171 </entry>
1172 <entry>
1173 <classname>Size_Policy</classname>
1174 </entry>
1175 <entry>
1176 <classname>hash_exponential_size_policy</classname>
1177 </entry>
1178 </row>
1179
1180 <row>
1181 <entry valign="top">
1182 <classname>Trigger_Policy</classname>
1183 </entry>
1184 <entry>
1185 <classname>hash_load_check_resize_trigger</classname> with
1186 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
1187 </entry>
1188 </row>
1189
1190 </tbody>
1191 </tgroup>
1192 </informaltable>
1193
1194
1195 <para>
1196 </para>
1197
1198 <para>
1199 </para>
1200
1201 <para>And the second graphic shows the results for the native and
1202 general-probe hash types. The function applied being a random
1203 integer timing test using <function>find</function>.
1204 </para>
1205
1206 <!-- results graphic 02 -->
1207 <informalfigure>
1208 <mediaobject>
1209 <imageobject>
1210 <imagedata align="center" format="PDF" scale="75"
1211 fileref="../images/pbds_gp_hash_random_int_subscript_timing_test_find_local.pdf"/>
1212 </imageobject>
1213 <imageobject>
1214 <imagedata align="center" format="PNG" scale="100"
1215 fileref="../images/pbds_gp_hash_random_int_subscript_timing_test_find_local.png"/>
1216 </imageobject>
1217 </mediaobject>
1218 </informalfigure>
1219
1220 <para>
1221 The abbreviated names in the legend of the graphic above are
1222 instantiated with the types in the following table.
1223 </para>
1224
1225
1226 <informaltable frame="all">
1227
1228 <tgroup cols="5" align="left" colsep="1" rowsep="1">
1229 <colspec colname="c1"/>
1230 <colspec colname="c2"/>
1231 <colspec colname="c3"/>
1232 <colspec colname="c4"/>
1233 <colspec colname="c5"/>
1234 <thead>
1235 <row>
1236 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
1237 <entry><emphasis>Parameter</emphasis></entry>
1238 <entry><emphasis>Details</emphasis></entry>
1239 <entry><emphasis>Parameter</emphasis></entry>
1240 <entry><emphasis>Details</emphasis></entry>
1241 </row>
1242 </thead>
1243
1244 <tbody>
1245
1246 <!-- native -->
1247 <row>
1248 <?dbhtml bgcolor="#B0B0B0" ?>
1249 <entry namest="c1" nameend="c5">
1250 n_hash_map_ncah
1251 </entry>
1252 </row>
1253
1254 <row>
1255 <entry>
1256 <classname>std::tr1::unordered_map</classname>
1257 </entry>
1258 <entry>
1259 <classname>cache_hash_code</classname>
1260 </entry>
1261 <entry>
1262 <constant>false</constant>
1263 </entry>
1264 <entry namest="c4" nameend="c5"></entry>
1265 </row>
1266
1267 <!-- hash 01 -->
1268 <row>
1269 <?dbhtml bgcolor="#B0B0B0" ?>
1270 <entry namest="c1" nameend="c5">
1271 gp_hash_mod_quadp_prime_nea_lc_1div8_1div2_nsth_map
1272 </entry>
1273 </row>
1274
1275 <row>
1276 <entry morerows="3" valign="top">
1277 <classname>gp_hash_table</classname>
1278 </entry>
1279 <entry>
1280 <classname>Comb_Hash_Fn</classname>
1281 </entry>
1282 <entry>
1283 <classname>direct_mod_range_hashing</classname>
1284 </entry>
1285 <entry namest="c4" nameend="c5"></entry>
1286 </row>
1287
1288 <row>
1289 <entry>
1290 <classname>Probe_Fn</classname>
1291 </entry>
1292 <entry>
1293 <classname>quadratic_probe_fn</classname>
1294 </entry>
1295 <entry namest="c4" nameend="c5"></entry>
1296 </row>
1297
1298 <row>
1299 <entry morerows="1" valign="top">
1300 <classname>Resize_Policy</classname>
1301 </entry>
1302 <entry morerows="1" valign="top">
1303 <classname>hash_standard_resize_policy</classname>
1304 </entry>
1305 <entry>
1306 <classname>Size_Policy</classname>
1307 </entry>
1308 <entry>
1309 <classname>hash_prime_size_policy</classname>
1310 </entry>
1311 </row>
1312
1313 <row>
1314 <entry valign="top">
1315 <classname>Trigger_Policy</classname>
1316 </entry>
1317 <entry>
1318 <classname>hash_load_check_resize_trigger</classname> with
1319 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
1320 </entry>
1321 </row>
1322
1323 <!-- hash 02 -->
1324 <row>
1325 <?dbhtml bgcolor="#B0B0B0" ?>
1326 <entry namest="c1" nameend="c5">
1327 gp_hash_mask_linp_exp_nea_lc_1div8_1div2_nsth_map
1328 </entry>
1329 </row>
1330
1331 <row>
1332 <entry morerows="3" valign="top">
1333 <classname>
1334 gp_hash_table
1335 </classname>
1336 </entry>
1337 <entry>
1338 <classname>Comb_Hash_Fn</classname>
1339 </entry>
1340 <entry>
1341 <classname>direct_mask_range_hashing</classname>
1342 </entry>
1343 <entry namest="c4" nameend="c5"></entry>
1344 </row>
1345
1346 <row>
1347 <entry>
1348 <classname>Probe_Fn</classname>
1349 </entry>
1350 <entry>
1351 <classname>linear_probe_fn</classname>
1352 </entry>
1353 <entry namest="c4" nameend="c5"></entry>
1354 </row>
1355
1356 <row>
1357 <entry morerows="1" valign="top">
1358 <classname>Resize_Policy</classname>
1359 </entry>
1360 <entry morerows="1" valign="top">
1361 <classname>hash_standard_resize_policy</classname>
1362 </entry>
1363 <entry>
1364 <classname>Size_Policy</classname>
1365 </entry>
1366 <entry>
1367 <classname>hash_exponential_size_policy</classname>
1368 </entry>
1369 </row>
1370
1371 <row>
1372 <entry valign="top">
1373 <classname>Trigger_Policy</classname>
1374 </entry>
1375 <entry>
1376 <classname>hash_load_check_resize_trigger</classname> with
1377 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
1378 </entry>
1379 </row>
1380
1381 </tbody>
1382 </tgroup>
1383 </informaltable>
1384
1385
1386 </section>
1387
1388 <section xml:id="hash.int_subscript_find.observations">
1389 <info><title>
1390 Observations
1391 </title></info>
1392 <para>This test shows similar results to Hash-Based
1393 Integer <classname>find</classname> Find Timing test.</para>
1394
1395 </section>
1396
1397 </section>
1398
1399 <!-- 04 <a href="hash_random_int_subscript_insert_timing_test"> -->
1400 <section xml:id="performance.hash.int_subscript_insert">
1401 <info><title>
1402 Integer Subscript <function>insert</function>
1403 </title></info>
1404 <para></para>
1405
1406 <section xml:id="hash.int_subscript_insert.info">
1407 <info><title>
1408 Description
1409 </title></info>
1410
1411 <para>This test inserts a number of values with uniform i.i.d.
1412 integer keys into a container, using
1413 <function>operator[]</function>. It measures the average time for
1414 <function>operator[]</function> as a function of the number of
1415 values inserted.</para>
1416
1417 <para>
1418 It uses the test file:
1419 <filename>
1420 performance/ext/pb_ds/random_int_subscript_insert_timing.cc
1421 </filename>
1422 </para>
1423
1424 <para>The test checks the effect of different underlying
1425 hash-tables.</para>
1426
1427
1428 </section>
1429
1430 <section xml:id="hash.int_subscript_insert.results">
1431 <info><title>
1432 Results
1433 </title></info>
1434
1435 <para>
1436 There are two sets of results for this type, one for
1437 collision-chaining hashes, and one for general-probe hashes.
1438 </para>
1439
1440 <para>The first graphic below shows the results for the native
1441 and collision-chaining hash types, using as the function
1442 applied an integer subscript timing test with
1443 <function>insert</function>.
1444 </para>
1445
1446 <!-- results graphic -->
1447 <informalfigure>
1448 <mediaobject>
1449 <imageobject>
1450 <imagedata align="center" format="PDF" scale="75"
1451 fileref="../images/pbds_cc_hash_random_int_subscript_timing_test_insert_local.pdf"/>
1452 </imageobject>
1453 <imageobject>
1454 <imagedata align="center" format="PNG" scale="100"
1455 fileref="../images/pbds_cc_hash_random_int_subscript_timing_test_insert_local.png"/>
1456 </imageobject>
1457 </mediaobject>
1458 </informalfigure>
1459
1460 <para>
1461 The abbreviated names in the legend of the graphic above are
1462 instantiated with the types in the following table.
1463 </para>
1464
1465 <informaltable frame="all">
1466
1467 <tgroup cols="5" align="left" colsep="1" rowsep="1">
1468 <colspec colname="c1"/>
1469 <colspec colname="c2"/>
1470 <colspec colname="c3"/>
1471 <colspec colname="c4"/>
1472 <colspec colname="c5"/>
1473 <thead>
1474 <row>
1475 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
1476 <entry><emphasis>Parameter</emphasis></entry>
1477 <entry><emphasis>Details</emphasis></entry>
1478 <entry><emphasis>Parameter</emphasis></entry>
1479 <entry><emphasis>Details</emphasis></entry>
1480 </row>
1481 </thead>
1482
1483 <tbody>
1484
1485 <!-- native -->
1486 <row>
1487 <?dbhtml bgcolor="#B0B0B0" ?>
1488 <entry namest="c1" nameend="c5">
1489 n_hash_map_ncah
1490 </entry>
1491 </row>
1492
1493 <row>
1494 <entry>
1495 <classname>std::tr1::unordered_map</classname>
1496 </entry>
1497 <entry>
1498 <classname>cache_hash_code</classname>
1499 </entry>
1500 <entry>
1501 <constant>false</constant>
1502 </entry>
1503 <entry namest="c4" nameend="c5"></entry>
1504 </row>
1505
1506 <!-- hash 01 -->
1507 <row>
1508 <?dbhtml bgcolor="#B0B0B0" ?>
1509 <entry namest="c1" nameend="c5">
1510 cc_hash_mod_prime_nea_lc_1div8_1div1_nsth_map
1511 </entry>
1512 </row>
1513
1514 <row>
1515 <entry morerows="2" valign="top">
1516 <classname>cc_hash_table</classname>
1517 </entry>
1518 <entry>
1519 <classname>Comb_Hash_Fn</classname>
1520 </entry>
1521 <entry>
1522 <classname>direct_mod_range_hashing</classname>
1523 </entry>
1524 <entry namest="c4" nameend="c5"></entry>
1525 </row>
1526
1527 <row>
1528 <entry morerows="1" valign="top">
1529 <classname>Resize_Policy</classname>
1530 </entry>
1531 <entry morerows="1" valign="top">
1532 <classname>hash_standard_resize_policy</classname>
1533 </entry>
1534 <entry>
1535 <classname>Size_Policy</classname>
1536 </entry>
1537 <entry>
1538 <classname>hash_prime_size_policy</classname>
1539 </entry>
1540 </row>
1541
1542 <row>
1543 <entry valign="top">
1544 <classname>Trigger_Policy</classname>
1545 </entry>
1546 <entry>
1547 <classname>hash_load_check_resize_trigger</classname> with
1548 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/1
1549 </entry>
1550 </row>
1551
1552 <!-- hash 02 -->
1553 <row>
1554 <?dbhtml bgcolor="#B0B0B0" ?>
1555 <entry namest="c1" nameend="c5">
1556 cc_hash_mod_prime_nea_lc_1div8_1div2_nsth_map
1557 </entry>
1558 </row>
1559
1560 <row>
1561 <entry morerows="2" valign="top">
1562 <classname>cc_hash_table</classname>
1563 </entry>
1564 <entry>
1565 <classname>Comb_Hash_Fn</classname>
1566 </entry>
1567 <entry>
1568 <classname>direct_mod_range_hashing</classname>
1569 </entry>
1570 <entry namest="c4" nameend="c5"></entry>
1571 </row>
1572
1573 <row>
1574 <entry morerows="1" valign="top">
1575 <classname>Resize_Policy</classname>
1576 </entry>
1577 <entry morerows="1" valign="top">
1578 <classname>hash_standard_resize_policy</classname>
1579 </entry>
1580 <entry>
1581 <classname>Size_Policy</classname>
1582 </entry>
1583 <entry>
1584 <classname>hash_prime_size_policy</classname>
1585 </entry>
1586 </row>
1587
1588 <row>
1589 <entry valign="top">
1590 <classname>Trigger_Policy</classname>
1591 </entry>
1592 <entry>
1593 <classname>hash_load_check_resize_trigger</classname> with
1594 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
1595 </entry>
1596 </row>
1597
1598 <!-- hash 03 -->
1599 <row>
1600 <?dbhtml bgcolor="#B0B0B0" ?>
1601 <entry namest="c1" nameend="c5">
1602 cc_hash_mask_exp_nea_lc_1div8_1div1_nsth_map
1603 </entry>
1604 </row>
1605
1606 <row>
1607 <entry morerows="2" valign="top">
1608 <classname>cc_hash_table</classname>
1609 </entry>
1610 <entry>
1611 <classname>Comb_Hash_Fn</classname>
1612 </entry>
1613 <entry>
1614 <classname>direct_mask_range_hashing</classname>
1615 </entry>
1616 <entry namest="c4" nameend="c5"></entry>
1617 </row>
1618
1619 <row>
1620 <entry morerows="1" valign="top">
1621 <classname>Resize_Policy</classname>
1622 </entry>
1623 <entry morerows="1" valign="top">
1624 <classname>hash_standard_resize_policy</classname>
1625 </entry>
1626 <entry>
1627 <classname>Size_Policy</classname>
1628 </entry>
1629 <entry>
1630 <classname>hash_exponential_size_policy</classname>
1631 </entry>
1632 </row>
1633
1634 <row>
1635 <entry valign="top">
1636 <classname>Trigger_Policy</classname>
1637 </entry>
1638 <entry>
1639 <classname>hash_load_check_resize_trigger</classname> with
1640 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/1
1641 </entry>
1642 </row>
1643
1644 <!-- hash 04 -->
1645 <row>
1646 <?dbhtml bgcolor="#B0B0B0" ?>
1647 <entry namest="c1" nameend="c5">
1648 cc_hash_mask_exp_nea_lc_1div8_1div2_nsth_map
1649 </entry>
1650 </row>
1651 <row>
1652 <entry morerows="2" valign="top">
1653 <classname>cc_hash_table</classname>
1654 </entry>
1655 <entry>
1656 <classname>Comb_Hash_Fn</classname>
1657 </entry>
1658 <entry>
1659 <classname>direct_mask_range_hashing</classname>
1660 </entry>
1661 <entry namest="c4" nameend="c5"></entry>
1662 </row>
1663
1664 <row>
1665 <entry morerows="1" valign="top">
1666 <classname>Resize_Policy</classname>
1667 </entry>
1668 <entry morerows="1" valign="top">
1669 <classname>hash_standard_resize_policy</classname>
1670 </entry>
1671 <entry>
1672 <classname>Size_Policy</classname>
1673 </entry>
1674 <entry>
1675 <classname>hash_exponential_size_policy</classname>
1676 </entry>
1677 </row>
1678
1679 <row>
1680 <entry valign="top">
1681 <classname>Trigger_Policy</classname>
1682 </entry>
1683 <entry>
1684 <classname>hash_load_check_resize_trigger</classname> with
1685 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
1686 </entry>
1687 </row>
1688
1689 </tbody>
1690 </tgroup>
1691 </informaltable>
1692
1693
1694 <para>
1695 </para>
1696
1697 <para>
1698 </para>
1699
1700 <para>And the second graphic shows the results for the native and
1701 general-probe hash types. The function applied being a random
1702 integer timing test using <function>find</function>.
1703 </para>
1704
1705 <!-- results graphic 02 -->
1706 <informalfigure>
1707 <mediaobject>
1708 <imageobject>
1709 <imagedata align="center" format="PDF" scale="75"
1710 fileref="../images/pbds_gp_hash_random_int_subscript_timing_test_insert_local.pdf"/>
1711 </imageobject>
1712 <imageobject>
1713 <imagedata align="center" format="PNG" scale="100"
1714 fileref="../images/pbds_gp_hash_random_int_subscript_timing_test_insert_local.png"/>
1715 </imageobject>
1716 </mediaobject>
1717 </informalfigure>
1718
1719 <para>
1720 The abbreviated names in the legend of the graphic above are
1721 instantiated with the types in the following table.
1722 </para>
1723
1724
1725 <informaltable frame="all">
1726
1727 <tgroup cols="5" align="left" colsep="1" rowsep="1">
1728 <colspec colname="c1"/>
1729 <colspec colname="c2"/>
1730 <colspec colname="c3"/>
1731 <colspec colname="c4"/>
1732 <colspec colname="c5"/>
1733 <thead>
1734 <row>
1735 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
1736 <entry><emphasis>Parameter</emphasis></entry>
1737 <entry><emphasis>Details</emphasis></entry>
1738 <entry><emphasis>Parameter</emphasis></entry>
1739 <entry><emphasis>Details</emphasis></entry>
1740 </row>
1741 </thead>
1742
1743 <tbody>
1744
1745 <!-- native -->
1746 <row>
1747 <?dbhtml bgcolor="#B0B0B0" ?>
1748 <entry namest="c1" nameend="c5">
1749 n_hash_map_ncah
1750 </entry>
1751 </row>
1752
1753 <row>
1754 <entry>
1755 <classname>std::tr1::unordered_map</classname>
1756 </entry>
1757 <entry>
1758 <classname>cache_hash_code</classname>
1759 </entry>
1760 <entry>
1761 <constant>false</constant>
1762 </entry>
1763 <entry namest="c4" nameend="c5"></entry>
1764 </row>
1765
1766 <!-- hash 01 -->
1767 <row>
1768 <?dbhtml bgcolor="#B0B0B0" ?>
1769 <entry namest="c1" nameend="c5">
1770 gp_hash_mod_quadp_prime_nea_lc_1div8_1div2_nsth_map
1771 </entry>
1772 </row>
1773
1774 <row>
1775 <entry morerows="3" valign="top">
1776 <classname>gp_hash_table</classname>
1777 </entry>
1778 <entry>
1779 <classname>Comb_Hash_Fn</classname>
1780 </entry>
1781 <entry>
1782 <classname>direct_mod_range_hashing</classname>
1783 </entry>
1784 <entry namest="c4" nameend="c5"></entry>
1785 </row>
1786
1787 <row>
1788 <entry>
1789 <classname>Probe_Fn</classname>
1790 </entry>
1791 <entry>
1792 <classname>quadratic_probe_fn</classname>
1793 </entry>
1794 <entry namest="c4" nameend="c5"></entry>
1795 </row>
1796
1797 <row>
1798 <entry morerows="1" valign="top">
1799 <classname>Resize_Policy</classname>
1800 </entry>
1801 <entry morerows="1" valign="top">
1802 <classname>hash_standard_resize_policy</classname>
1803 </entry>
1804 <entry>
1805 <classname>Size_Policy</classname>
1806 </entry>
1807 <entry>
1808 <classname>hash_prime_size_policy</classname>
1809 </entry>
1810 </row>
1811
1812 <row>
1813 <entry valign="top">
1814 <classname>Trigger_Policy</classname>
1815 </entry>
1816 <entry>
1817 <classname>hash_load_check_resize_trigger</classname> with
1818 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
1819 </entry>
1820 </row>
1821
1822 <!-- hash 02 -->
1823 <row>
1824 <?dbhtml bgcolor="#B0B0B0" ?>
1825 <entry namest="c1" nameend="c5">
1826 gp_hash_mask_linp_exp_nea_lc_1div8_1div2_nsth_map
1827 </entry>
1828 </row>
1829
1830 <row>
1831 <entry morerows="3" valign="top">
1832 <classname>
1833 gp_hash_table
1834 </classname>
1835 </entry>
1836 <entry>
1837 <classname>Comb_Hash_Fn</classname>
1838 </entry>
1839 <entry>
1840 <classname>direct_mask_range_hashing</classname>
1841 </entry>
1842 <entry namest="c4" nameend="c5"></entry>
1843 </row>
1844
1845 <row>
1846 <entry>
1847 <classname>Probe_Fn</classname>
1848 </entry>
1849 <entry>
1850 <classname>linear_probe_fn</classname>
1851 </entry>
1852 <entry namest="c4" nameend="c5"></entry>
1853 </row>
1854
1855 <row>
1856 <entry morerows="1" valign="top">
1857 <classname>Resize_Policy</classname>
1858 </entry>
1859 <entry morerows="1" valign="top">
1860 <classname>hash_standard_resize_policy</classname>
1861 </entry>
1862 <entry>
1863 <classname>Size_Policy</classname>
1864 </entry>
1865 <entry>
1866 <classname>hash_exponential_size_policy</classname>
1867 </entry>
1868 </row>
1869
1870 <row>
1871 <entry valign="top">
1872 <classname>Trigger_Policy</classname>
1873 </entry>
1874 <entry>
1875 <classname>hash_load_check_resize_trigger</classname> with
1876 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
1877 </entry>
1878 </row>
1879
1880 </tbody>
1881 </tgroup>
1882 </informaltable>
1883
1884
1885 </section>
1886
1887 <section xml:id="hash.int_subscript_insert.observations">
1888 <info><title>
1889 Observations
1890 </title></info>
1891
1892 <para>In this setting, as in Hash-Based Text
1893 <function>find</function> Find Timing test and Hash-Based
1894 Integer <function>find</function> Find Timing test , the choice
1895 of underlying hash-table underlying hash-table affects performance
1896 most, then the range-hashing scheme, and
1897 finally any other policies.</para>
1898 <para>There are some differences, however:</para>
1899 <orderedlist>
1900 <listitem><para>In this setting, probing tables function sometimes more
1901 efficiently than collision-chaining tables.
1902 This is explained shortly.</para></listitem>
1903 <listitem><para>The performance graphs have a "saw-tooth" shape. The
1904 average insert time rises and falls. As values are inserted
1905 into the container, the load factor grows larger. Eventually,
1906 a resize occurs. The reallocations and rehashing are
1907 relatively expensive. After this, the load factor is smaller
1908 than before.</para></listitem>
1909 </orderedlist>
1910
1911 <para>Collision-chaining containers use indirection for greater
1912 flexibility; probing containers store values contiguously, in
1913 an array (see Figure Motivation::Different
1914 underlying data structures A and B, respectively). It
1915 follows that for simple data types, probing containers access
1916 their allocator less frequently than collision-chaining
1917 containers, (although they still have less efficient probing
1918 sequences). This explains why some probing containers fare
1919 better than collision-chaining containers in this case.</para>
1920
1921 <para>
1922 Within each type of hash-table, the range-hashing scheme affects
1923 performance more than other policies. This is similar to the
1924 situation in Hash-Based Text
1925 <function>find</function> Find Timing Test and Hash-Based
1926 Integer <function>find</function> Find Timing Test.
1927 Unsurprisingly, however, containers with lower α<subscript>max</subscript> perform worse in this case,
1928 since more re-hashes are performed.</para>
1929
1930 </section>
1931
1932 </section>
1933
1934
1935 <!-- 05 <a href="hash_zlob_random_int_find_find_timing_test"> -->
1936
1937 <!-- 05 <a href="hash_zlob_random_int_find_find_timing_test"> -->
1938 <section xml:id="performance.hash.zlob_int_find">
1939 <info><title>
1940 Integer <function>find</function> with Skewed-Distribution
1941 </title></info>
1942 <para></para>
1943
1944 <section xml:id="hash.zlob_int_find.info">
1945 <info><title>
1946 Description
1947 </title></info>
1948
1949 <para>This test inserts a number of values with a markedly
1950 non-uniform integer keys into a container, then performs
1951 a series of finds using <function>find</function>. It measures the average
1952 time for <function>find</function> as a function of the number of values in
1953 the containers. The keys are generated as follows. First, a
1954 uniform integer is created. Then it is then shifted left 8 bits.</para>
1955
1956 <para>
1957 It uses the test file:
1958 <filename>
1959 performance/ext/pb_ds/hash_zlob_random_int_find_timing.cc
1960 </filename>
1961 </para>
1962
1963 <para>The test checks the effect of different range-hashing
1964 functions and trigger policies.</para>
1965
1966
1967 </section>
1968
1969 <section xml:id="hash.zlob_int_find.results">
1970 <info><title>
1971 Results
1972 </title></info>
1973
1974 <para>The graphic below show the results for the native, collision-chaining, and general-probing hash types.
1975 </para>
1976
1977 <!-- results graphic -->
1978 <informalfigure>
1979 <mediaobject>
1980 <imageobject>
1981 <imagedata align="center" format="PDF" scale="75"
1982 fileref="../images/pbds_hash_zlob_random_int_find_timing_test_local.pdf"/>
1983 </imageobject>
1984 <imageobject>
1985 <imagedata align="center" format="PNG" scale="100"
1986 fileref="../images/pbds_hash_zlob_random_int_find_timing_test_local.png"/>
1987 </imageobject>
1988 </mediaobject>
1989 </informalfigure>
1990
1991 <para>
1992 The abbreviated names in the legend of the graphic above are
1993 instantiated with the types in the following table.
1994 </para>
1995
1996
1997 <informaltable frame="all">
1998
1999 <tgroup cols="5" align="left" colsep="1" rowsep="1">
2000 <colspec colname="c1"/>
2001 <colspec colname="c2"/>
2002 <colspec colname="c3"/>
2003 <colspec colname="c4"/>
2004 <colspec colname="c5"/>
2005 <thead>
2006 <row>
2007 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
2008 <entry><emphasis>Parameter</emphasis></entry>
2009 <entry><emphasis>Details</emphasis></entry>
2010 <entry><emphasis>Parameter</emphasis></entry>
2011 <entry><emphasis>Details</emphasis></entry>
2012 </row>
2013 </thead>
2014
2015 <tbody>
2016
2017 <!-- native -->
2018 <row>
2019 <?dbhtml bgcolor="#B0B0B0" ?>
2020 <entry namest="c1" nameend="c5">
2021 n_hash_map_ncah
2022 </entry>
2023 </row>
2024
2025 <row>
2026 <entry>
2027 <classname>std::tr1::unordered_map</classname>
2028 </entry>
2029 <entry>
2030 <classname>cache_hash_code</classname>
2031 </entry>
2032 <entry>
2033 <constant>false</constant>
2034 </entry>
2035 <entry namest="c4" nameend="c5"></entry>
2036 </row>
2037
2038 <!-- hash 01 -->
2039 <row>
2040 <?dbhtml bgcolor="#B0B0B0" ?>
2041 <entry namest="c1" nameend="c5">
2042 cc_hash_mod_prime_nea_lc_1div8_1div1_nsth_map
2043 </entry>
2044 </row>
2045
2046 <row>
2047 <entry morerows="2" valign="top">
2048 <classname>cc_hash_table</classname>
2049 </entry>
2050 <entry>
2051 <classname>Comb_Hash_Fn</classname>
2052 </entry>
2053 <entry>
2054 <classname>direct_mod_range_hashing</classname>
2055 </entry>
2056 <entry namest="c4" nameend="c5"></entry>
2057 </row>
2058
2059 <row>
2060 <entry morerows="1" valign="top">
2061 <classname>Resize_Policy</classname>
2062 </entry>
2063 <entry morerows="1" valign="top">
2064 <classname>hash_standard_resize_policy</classname>
2065 </entry>
2066 <entry>
2067 <classname>Size_Policy</classname>
2068 </entry>
2069 <entry>
2070 <classname>hash_prime_size_policy</classname>
2071 </entry>
2072 </row>
2073
2074 <row>
2075 <entry valign="top">
2076 <classname>Trigger_Policy</classname>
2077 </entry>
2078 <entry>
2079 <classname>hash_load_check_resize_trigger</classname> with
2080 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/1
2081 </entry>
2082 </row>
2083
2084 <!-- hash 02 -->
2085 <row>
2086 <?dbhtml bgcolor="#B0B0B0" ?>
2087 <entry namest="c1" nameend="c5">
2088 cc_hash_mask_exp_nea_lc_1div8_1div1_nsth_map
2089 </entry>
2090 </row>
2091
2092 <row>
2093 <entry morerows="2" valign="top">
2094 <classname>
2095 cc_hash_table
2096 </classname>
2097 </entry>
2098 <entry>
2099 <classname>Comb_Hash_Fn</classname>
2100 </entry>
2101 <entry>
2102 <classname>direct_mask_range_hashing</classname>
2103 </entry>
2104 <entry namest="c4" nameend="c5"></entry>
2105 </row>
2106
2107 <row>
2108 <entry morerows="1" valign="top">
2109 <classname>Resize_Policy</classname>
2110 </entry>
2111 <entry morerows="1" valign="top">
2112 <classname>hash_standard_resize_policy</classname>
2113 </entry>
2114 <entry>
2115 <classname>Size_Policy</classname>
2116 </entry>
2117 <entry>
2118 <classname>hash_exponential_size_policy</classname>
2119 </entry>
2120 </row>
2121
2122 <row>
2123 <entry valign="top">
2124 <classname>Trigger_Policy</classname>
2125 </entry>
2126 <entry>
2127 <classname>hash_load_check_resize_trigger</classname> with
2128 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/1
2129 </entry>
2130 </row>
2131
2132 <!-- hash 01 -->
2133 <row>
2134 <?dbhtml bgcolor="#B0B0B0" ?>
2135 <entry namest="c1" nameend="c5">
2136 gp_hash_mod_quadp_prime_nea_lc_1div8_1div2_nsth_map
2137 </entry>
2138 </row>
2139
2140 <row>
2141 <entry morerows="3" valign="top">
2142 <classname>gp_hash_table</classname>
2143 </entry>
2144 <entry>
2145 <classname>Comb_Hash_Fn</classname>
2146 </entry>
2147 <entry>
2148 <classname>direct_mod_range_hashing</classname>
2149 </entry>
2150 <entry namest="c4" nameend="c5"></entry>
2151 </row>
2152
2153 <row>
2154 <entry>
2155 <classname>Probe_Fn</classname>
2156 </entry>
2157 <entry>
2158 <classname>quadratic_probe_fn</classname>
2159 </entry>
2160 <entry namest="c4" nameend="c5"></entry>
2161 </row>
2162
2163 <row>
2164 <entry morerows="1" valign="top">
2165 <classname>Resize_Policy</classname>
2166 </entry>
2167 <entry morerows="1" valign="top">
2168 <classname>hash_standard_resize_policy</classname>
2169 </entry>
2170 <entry>
2171 <classname>Size_Policy</classname>
2172 </entry>
2173 <entry>
2174 <classname>hash_prime_size_policy</classname>
2175 </entry>
2176 </row>
2177
2178 <row>
2179 <entry valign="top">
2180 <classname>Trigger_Policy</classname>
2181 </entry>
2182 <entry>
2183 <classname>hash_load_check_resize_trigger</classname> with
2184 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
2185 </entry>
2186 </row>
2187
2188
2189 </tbody>
2190 </tgroup>
2191 </informaltable>
2192
2193 </section>
2194
2195 <section xml:id="hash.zlob_int_find.observations">
2196 <info><title>
2197 Observations
2198 </title></info>
2199
2200 <para>In this setting, the distribution of keys is so skewed that
2201 the underlying hash-table type affects performance marginally.
2202 (This is in contrast with Hash-Based Text
2203 <function>find</function> Find Timing Test, Hash-Based
2204 Integer <function>find</function> Find Timing Test, Hash-Based
2205 Integer Subscript Find Timing Test and Hash-Based
2206 Integer Subscript Insert Timing Test.)</para>
2207
2208 <para>The range-hashing scheme affects performance dramatically. A
2209 mask-based range-hashing scheme effectively maps all values
2210 into the same bucket. Access degenerates into a search within
2211 an unordered linked-list. In the graphic above, it should be noted that
2212 <classname>std::tr1::unordered_map</classname> is hard-wired currently to mod-based and mask-based schemes,
2213 respectively.</para>
2214
2215 <para>When observing the settings of this test, it is apparent
2216 that the keys' distribution is far from natural. One might ask
2217 if the test is not contrived to show that, in some cases,
2218 mod-based range hashing does better than mask-based range
2219 hashing. This is, in fact just the case. A
2220 more natural case in which mod-based range hashing is better was not encountered.
2221 Thus the inescapable conclusion: real-life key distributions are handled better
2222 with an appropriate hash function and a mask-based
2223 range-hashing function. (<filename>pb_ds/example/hash_shift_mask.cc</filename>
2224 shows an example of handling this a-priori known skewed
2225 distribution with a mask-based range-hashing function). If hash
2226 performance is bad, a χ<superscript>2</superscript> test can be used
2227 to check how to transform it into a more uniform
2228 distribution.</para>
2229 <para>For this reason, this library's default range-hashing
2230 function is mask-based.</para>
2231
2232 </section>
2233
2234 </section>
2235
2236
2237 <!-- 06 <a href="hash_random_int_erase_mem_usage_test"> -->
2238
2239 <!-- 06 <a href="hash_random_int_erase_mem_usage_test"> -->
2240 <section xml:id="performance.hash.erase_mem">
2241 <info><title>
2242 Erase Memory Use
2243 </title></info>
2244 <para></para>
2245
2246 <section xml:id="hash.erase_mem.info">
2247 <info><title>
2248 Description
2249 </title></info>
2250
2251 <para>This test inserts a number of uniform integer keys
2252 into a container, then erases all keys except one. It measures
2253 the final size of the container.</para>
2254
2255 <para>
2256 It uses the test file:
2257 <filename>
2258 performance/ext/pb_ds/hash_random_int_erase_mem_usage.cc
2259 </filename>
2260 </para>
2261
2262
2263 <para>The test checks how containers adjust internally as their
2264 logical size decreases.</para>
2265
2266 </section>
2267
2268 <section xml:id="hash.erase_mem.results">
2269 <info><title>
2270 Results
2271 </title></info>
2272
2273 <para>The graphic below show the results for the native, collision-chaining, and general-probing hash types.
2274 </para>
2275
2276 <!-- results graphic -->
2277 <informalfigure>
2278 <mediaobject>
2279 <imageobject>
2280 <imagedata align="center" format="PDF" scale="75"
2281 fileref="../images/pbds_hash_random_int_erase_mem_usage_test_local.pdf"/>
2282 </imageobject>
2283 <imageobject>
2284 <imagedata align="center" format="PNG" scale="100"
2285 fileref="../images/pbds_hash_random_int_erase_mem_usage_test_local.png"/>
2286 </imageobject>
2287 </mediaobject>
2288 </informalfigure>
2289
2290 <para>
2291 The abbreviated names in the legend of the graphic above are
2292 instantiated with the types in the following table.
2293 </para>
2294
2295
2296 <informaltable frame="all">
2297
2298 <tgroup cols="5" align="left" colsep="1" rowsep="1">
2299 <colspec colname="c1"/>
2300 <colspec colname="c2"/>
2301 <colspec colname="c3"/>
2302 <colspec colname="c4"/>
2303 <colspec colname="c5"/>
2304 <thead>
2305 <row>
2306 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
2307 <entry><emphasis>Parameter</emphasis></entry>
2308 <entry><emphasis>Details</emphasis></entry>
2309 <entry><emphasis>Parameter</emphasis></entry>
2310 <entry><emphasis>Details</emphasis></entry>
2311 </row>
2312 </thead>
2313
2314 <tbody>
2315
2316 <!-- native -->
2317 <row>
2318 <?dbhtml bgcolor="#B0B0B0" ?>
2319 <entry namest="c1" nameend="c5">
2320 n_hash_map_ncah
2321 </entry>
2322 </row>
2323
2324 <row>
2325 <entry>
2326 <classname>std::tr1::unordered_map</classname>
2327 </entry>
2328 <entry>
2329 <classname>cache_hash_code</classname>
2330 </entry>
2331 <entry>
2332 <constant>false</constant>
2333 </entry>
2334 <entry namest="c4" nameend="c5"></entry>
2335 </row>
2336
2337 <!-- hash 01 -->
2338 <row>
2339 <?dbhtml bgcolor="#B0B0B0" ?>
2340 <entry namest="c1" nameend="c5">
2341 cc_hash_mod_prime_nea_lc_1div8_1div1_nsth_map
2342 </entry>
2343 </row>
2344
2345 <row>
2346 <entry morerows="2" valign="top">
2347 <classname>cc_hash_table</classname>
2348 </entry>
2349 <entry>
2350 <classname>Comb_Hash_Fn</classname>
2351 </entry>
2352 <entry>
2353 <classname>direct_mod_range_hashing</classname>
2354 </entry>
2355 <entry namest="c4" nameend="c5"></entry>
2356 </row>
2357
2358 <row>
2359 <entry morerows="1" valign="top">
2360 <classname>Resize_Policy</classname>
2361 </entry>
2362 <entry morerows="1" valign="top">
2363 <classname>hash_standard_resize_policy</classname>
2364 </entry>
2365 <entry>
2366 <classname>Size_Policy</classname>
2367 </entry>
2368 <entry>
2369 <classname>hash_prime_size_policy</classname>
2370 </entry>
2371 </row>
2372
2373 <row>
2374 <entry valign="top">
2375 <classname>Trigger_Policy</classname>
2376 </entry>
2377 <entry>
2378 <classname>hash_load_check_resize_trigger</classname> with
2379 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/1
2380 </entry>
2381 </row>
2382
2383 <!-- hash 02 -->
2384 <row>
2385 <?dbhtml bgcolor="#B0B0B0" ?>
2386 <entry namest="c1" nameend="c5">
2387 cc_hash_mask_exp_nea_lc_1div8_1div2_nsth_map
2388 </entry>
2389 </row>
2390
2391 <row>
2392 <entry morerows="2" valign="top">
2393 <classname>
2394 cc_hash_table
2395 </classname>
2396 </entry>
2397 <entry>
2398 <classname>Comb_Hash_Fn</classname>
2399 </entry>
2400 <entry>
2401 <classname>direct_mask_range_hashing</classname>
2402 </entry>
2403 <entry namest="c4" nameend="c5"></entry>
2404 </row>
2405
2406 <row>
2407 <entry morerows="1" valign="top">
2408 <classname>Resize_Policy</classname>
2409 </entry>
2410 <entry morerows="1" valign="top">
2411 <classname>hash_standard_resize_policy</classname>
2412 </entry>
2413 <entry>
2414 <classname>Size_Policy</classname>
2415 </entry>
2416 <entry>
2417 <classname>hash_exponential_size_policy</classname>
2418 </entry>
2419 </row>
2420
2421 <row>
2422 <entry valign="top">
2423 <classname>Trigger_Policy</classname>
2424 </entry>
2425 <entry>
2426 <classname>hash_load_check_resize_trigger</classname> with
2427 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
2428 </entry>
2429 </row>
2430
2431 <!-- hash 03 -->
2432 <row>
2433 <?dbhtml bgcolor="#B0B0B0" ?>
2434 <entry namest="c1" nameend="c5">
2435 gp_hash_mask_linp_exp_nea_lc_1div8_1div2_nsth_set
2436 </entry>
2437 </row>
2438
2439 <row>
2440 <entry morerows="3" valign="top">
2441 <classname>gp_hash_table</classname>
2442 </entry>
2443 <entry>
2444 <classname>Comb_Hash_Fn</classname>
2445 </entry>
2446 <entry>
2447 <classname>direct_mask_range_hashing</classname>
2448 </entry>
2449 <entry namest="c4" nameend="c5"></entry>
2450 </row>
2451
2452 <row>
2453 <entry>
2454 <classname>Probe_Fn</classname>
2455 </entry>
2456 <entry>
2457 <classname>linear_probe_fn</classname>
2458 </entry>
2459 <entry namest="c4" nameend="c5"></entry>
2460 </row>
2461
2462 <row>
2463 <entry morerows="1" valign="top">
2464 <classname>Resize_Policy</classname>
2465 </entry>
2466 <entry morerows="1" valign="top">
2467 <classname>hash_standard_resize_policy</classname>
2468 </entry>
2469 <entry>
2470 <classname>Size_Policy</classname>
2471 </entry>
2472 <entry>
2473 <classname>hash_exponential_size_policy</classname>
2474 </entry>
2475 </row>
2476
2477 <row>
2478 <entry valign="top">
2479 <classname>Trigger_Policy</classname>
2480 </entry>
2481 <entry>
2482 <classname>hash_load_check_resize_trigger</classname> with
2483 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
2484 </entry>
2485 </row>
2486
2487
2488 </tbody>
2489 </tgroup>
2490 </informaltable>
2491
2492 </section>
2493
2494 <section xml:id="hash.erase_mem.observations">
2495 <info><title>
2496 Observations
2497 </title></info>
2498 <para>The standard's hash-based containers act very differently than trees in
2499 this respect. When erasing numerous keys from an standard
2500 associative-container, the resulting memory user varies greatly
2501 depending on whether the container is tree-based or hash-based.
2502 This is a fundamental consequence of the standard's interface for
2503 associative containers, and it is not due to a specific
2504 implementation.</para>
2505 </section>
2506
2507 </section>
2508 </section>
2509
2510
2511 <section xml:id="performance.branch">
2512 <info><title>Branch-Based</title></info>
2513 <para></para>
2514
2515 <!-- 01 <a href="tree_text_insert_timing_test"> -->
2516 <section xml:id="performance.branch.text_insert">
2517 <info><title>
2518 Text <function>insert</function>
2519 </title></info>
2520 <para></para>
2521
2522 <section xml:id="branch.text_insert.info">
2523 <info><title>
2524 Description
2525 </title></info>
2526
2527
2528 <para>This test inserts a number of values with keys from an arbitrary
2529 text ([ wickland96thirty ]) into a container
2530 using <function>insert</function> . It measures the average time
2531 for <function>insert</function> as a function of the number of
2532 values inserted.</para>
2533
2534 <para>The test checks the effect of different underlying
2535 data structures.</para>
2536
2537 <para>
2538 It uses the test file:
2539 <filename>
2540 performance/ext/pb_ds/tree_text_insert_timing.cc
2541 </filename>
2542 </para>
2543
2544
2545 </section>
2546
2547 <section xml:id="branch.text_insert.results">
2548 <info><title>
2549 Results
2550 </title></info>
2551
2552 <para>The three graphics below show the results for the native
2553 tree and this library's node-based trees, the native tree and
2554 this library's vector-based trees, and the native tree
2555 and this library's PATRICIA-trie, respectively.
2556 </para>
2557
2558 <para>The graphic immediately below shows the results for the
2559 native tree type and several node-based tree types.
2560 </para>
2561
2562 <!-- results graphic -->
2563 <informalfigure>
2564 <mediaobject>
2565 <imageobject>
2566 <imagedata align="center" format="PDF" scale="75"
2567 fileref="../images/pbds_tree_text_insert_timing_test_node_tree_local.pdf"/>
2568 </imageobject>
2569 <imageobject>
2570 <imagedata align="center" format="PNG" scale="100"
2571 fileref="../images/pbds_tree_text_insert_timing_test_node_tree_local.png"/>
2572 </imageobject>
2573 </mediaobject>
2574
2575
2576 <para>
2577 The abbreviated names in the legend of the graphic above are
2578 instantiated with the types in the following table.
2579 </para>
2580 </informalfigure>
2581
2582 <informaltable frame="all">
2583 <tgroup cols="3" align="left" colsep="1" rowsep="1">
2584 <colspec colname="c1"/>
2585 <colspec colname="c2"/>
2586 <colspec colname="c3"/>
2587 <thead>
2588 <row>
2589 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
2590 <entry><emphasis>Parameter</emphasis></entry>
2591 <entry><emphasis>Details</emphasis></entry>
2592 </row>
2593 </thead>
2594
2595 <tbody>
2596
2597 <!-- native -->
2598 <row>
2599 <?dbhtml bgcolor="#B0B0B0" ?>
2600 <entry namest="c1" nameend="c3">
2601 n_map
2602 </entry>
2603 </row>
2604
2605 <row>
2606 <entry>
2607 <classname>std::map</classname>
2608 </entry>
2609 <entry namest="c2" nameend="c3"></entry>
2610 </row>
2611
2612 <!-- branch 01 -->
2613 <row>
2614 <?dbhtml bgcolor="#B0B0B0" ?>
2615 <entry namest="c1" nameend="c3">
2616 splay_tree_map
2617 </entry>
2618 </row>
2619
2620 <row>
2621 <entry morerows="1" valign="top">
2622 <classname>tree</classname>
2623 </entry>
2624 <entry>
2625 <classname>Tag</classname>
2626 </entry>
2627 <entry>
2628 <classname>splay_tree_tag</classname>
2629 </entry>
2630 </row>
2631
2632 <row>
2633 <entry>
2634 <classname>Node_update</classname>
2635 </entry>
2636 <entry>
2637 <classname>null_node_update</classname>
2638 </entry>
2639 </row>
2640
2641
2642 <!-- branch 02 -->
2643 <row>
2644 <?dbhtml bgcolor="#B0B0B0" ?>
2645 <entry namest="c1" nameend="c3">
2646 rb_tree_map
2647 </entry>
2648 </row>
2649
2650 <row>
2651 <entry morerows="1" valign="top">
2652 <classname>tree</classname>
2653 </entry>
2654 <entry>
2655 <classname>Tag</classname>
2656 </entry>
2657 <entry>
2658 <classname>rb_tree_tag</classname>
2659 </entry>
2660 </row>
2661
2662 <row>
2663 <entry>
2664 <classname>Node_update</classname>
2665 </entry>
2666 <entry>
2667 <classname>null_node_update</classname>
2668 </entry>
2669 </row>
2670
2671 </tbody>
2672 </tgroup>
2673 </informaltable>
2674
2675
2676
2677 <para>The graphic below shows the results for the
2678 native tree type and a vector-based tree type.
2679 </para>
2680
2681 <!-- results graphic -->
2682 <informalfigure>
2683 <mediaobject>
2684 <imageobject>
2685 <imagedata align="center" format="PDF" scale="75"
2686 fileref="../images/pbds_tree_text_insert_timing_test_vector_tree_local.pdf"/>
2687 </imageobject>
2688 <imageobject>
2689 <imagedata align="center" format="PNG" scale="100"
2690 fileref="../images/pbds_tree_text_insert_timing_test_vector_tree_local.png"/>
2691 </imageobject>
2692 </mediaobject>
2693 </informalfigure>
2694
2695 <para>
2696 The abbreviated names in the legend of the graphic above are
2697 instantiated with the types in the following table.
2698 </para>
2699
2700
2701 <informaltable frame="all">
2702
2703 <tgroup cols="3" align="left" colsep="1" rowsep="1">
2704 <colspec colname="c1"/>
2705 <colspec colname="c2"/>
2706 <colspec colname="c3"/>
2707 <thead>
2708 <row>
2709 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
2710 <entry><emphasis>Parameter</emphasis></entry>
2711 <entry><emphasis>Details</emphasis></entry>
2712 </row>
2713 </thead>
2714
2715 <tbody>
2716
2717 <!-- native -->
2718 <row>
2719 <?dbhtml bgcolor="#B0B0B0" ?>
2720 <entry namest="c1" nameend="c3">
2721 n_map
2722 </entry>
2723 </row>
2724
2725 <row>
2726 <entry>
2727 <classname>std::map</classname>
2728 </entry>
2729 <entry namest="c2" nameend="c3"></entry>
2730 </row>
2731
2732 <!-- branch 01 -->
2733 <row>
2734 <?dbhtml bgcolor="#B0B0B0" ?>
2735 <entry namest="c1" nameend="c3">
2736 ov_tree_map
2737 </entry>
2738 </row>
2739
2740 <row>
2741 <entry morerows="1" valign="top">
2742 <classname>tree</classname>
2743 </entry>
2744 <entry>
2745 <classname>Tag</classname>
2746 </entry>
2747 <entry>
2748 <classname>ov_tree_tag</classname>
2749 </entry>
2750 </row>
2751
2752 <row>
2753 <entry>
2754 <classname>Node_update</classname>
2755 </entry>
2756 <entry>
2757 <classname>null_node_update</classname>
2758 </entry>
2759 </row>
2760
2761
2762 </tbody>
2763 </tgroup>
2764 </informaltable>
2765
2766
2767
2768
2769 <para>The graphic below shows the results for the
2770 native tree type and a PATRICIA trie type.
2771 </para>
2772
2773 <!-- results graphic -->
2774 <informalfigure>
2775 <mediaobject>
2776 <imageobject>
2777 <imagedata align="center" format="PDF" scale="75"
2778 fileref="../images/pbds_tree_text_insert_timing_test_pat_trie_local.pdf"/>
2779 </imageobject>
2780 <imageobject>
2781 <imagedata align="center" format="PNG" scale="100"
2782 fileref="../images/pbds_tree_text_insert_timing_test_pat_trie_local.png"/>
2783 </imageobject>
2784 </mediaobject>
2785 </informalfigure>
2786
2787 <para>
2788 The abbreviated names in the legend of the graphic above are
2789 instantiated with the types in the following table.
2790 </para>
2791
2792
2793 <informaltable frame="all">
2794
2795 <tgroup cols="3" align="left" colsep="1" rowsep="1">
2796 <colspec colname="c1"/>
2797 <colspec colname="c2"/>
2798 <colspec colname="c3"/>
2799 <thead>
2800 <row>
2801 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
2802 <entry><emphasis>Parameter</emphasis></entry>
2803 <entry><emphasis>Details</emphasis></entry>
2804 </row>
2805 </thead>
2806
2807 <tbody>
2808
2809 <!-- native -->
2810 <row>
2811 <?dbhtml bgcolor="#B0B0B0" ?>
2812 <entry namest="c1" nameend="c3">
2813 n_map
2814 </entry>
2815 </row>
2816
2817 <row>
2818 <entry>
2819 <classname>std::map</classname>
2820 </entry>
2821 <entry namest="c2" nameend="c3"></entry>
2822 </row>
2823
2824 <!-- branch 01 -->
2825 <row>
2826 <?dbhtml bgcolor="#B0B0B0" ?>
2827 <entry namest="c1" nameend="c3">
2828 pat_trie_map
2829 </entry>
2830 </row>
2831
2832 <row>
2833 <entry morerows="1" valign="top">
2834 <classname>tree</classname>
2835 </entry>
2836 <entry>
2837 <classname>Tag</classname>
2838 </entry>
2839 <entry>
2840 <classname>pat_trie_tag</classname>
2841 </entry>
2842 </row>
2843
2844 <row>
2845 <entry>
2846 <classname>Node_update</classname>
2847 </entry>
2848 <entry>
2849 <classname>null_node_update</classname>
2850 </entry>
2851 </row>
2852
2853
2854 </tbody>
2855 </tgroup>
2856 </informaltable>
2857
2858 </section>
2859
2860 <section xml:id="branch.text_insert.observations">
2861 <info><title>
2862 Observations
2863 </title></info>
2864
2865 <para>Observing the first graphic implies that for this setting, a splay tree
2866 (<classname>tree</classname> with <classname>Tag
2867 </classname> = <classname>splay_tree_tag</classname>) does not do
2868 well. See also the Branch-Based
2869 Text <function>find</function> Find Timing Test. The two
2870 red-black trees perform better.</para>
2871
2872 <para>Observing the second graphic, an ordered-vector tree
2873 (<classname>tree</classname> with <classname>Tag
2874 </classname> = <classname>ov_tree_tag</classname>) performs
2875 abysmally. Inserting into this type of tree has linear complexity
2876 [ austern00noset].</para>
2877
2878 <para>Observing the third and last graphic, A PATRICIA trie
2879 (<classname>trie</classname> with <classname>Tag
2880 </classname> = <classname>pat_trie_tag</classname>) has abysmal
2881 performance, as well. This is not that surprising, since a
2882 large-fan-out PATRICIA trie works like a hash table with
2883 collisions resolved by a sub-trie. Each time a collision is
2884 encountered, a new "hash-table" is built A large fan-out PATRICIA
2885 trie, however, doe does well in look-ups (see Branch-Based
2886 Text <function>find</function> Find Timing Test). It may be
2887 beneficial in semi-static settings.</para>
2888 </section>
2889
2890 </section>
2891
2892
2893 <!-- 02 <a href="tree_text_find_find_timing_test"> -->
2894 <section xml:id="performance.branch.text_find">
2895 <info><title>
2896 Text <function>find</function>
2897 </title></info>
2898 <para></para>
2899
2900 <section xml:id="branch.text_find.info">
2901 <info><title>
2902 Description
2903 </title></info>
2904
2905
2906 <para>This test inserts a number of values with keys from an
2907 arbitrary text ([wickland96thirty]) into
2908 a container, then performs a series of finds using
2909 <function>find</function>. It measures the average time
2910 for <function>find</function> as a function of the number of
2911 values inserted.</para>
2912
2913 <para>
2914 It uses the test file:
2915 <filename>
2916 performance/ext/pb_ds/text_find_timing.cc
2917 </filename>
2918 </para>
2919
2920
2921 <para>The test checks the effect of different underlying
2922 data structures.</para>
2923
2924 </section>
2925
2926 <section xml:id="branch.text_find.results">
2927 <info><title>
2928 Results
2929 </title></info>
2930
2931 <para>The graphic immediately below shows the results for the
2932 native tree type and several other tree types.
2933 </para>
2934
2935 <!-- results graphic -->
2936 <informalfigure>
2937 <mediaobject>
2938 <imageobject>
2939 <imagedata align="center" format="PDF" scale="75"
2940 fileref="../images/pbds_text_find_timing_test_tree_like_local.pdf"/>
2941 </imageobject>
2942 <imageobject>
2943 <imagedata align="center" format="PNG" scale="100"
2944 fileref="../images/pbds_text_find_timing_test_tree_like_local.png"/>
2945 </imageobject>
2946 </mediaobject>
2947 </informalfigure>
2948
2949 <para>
2950 The abbreviated names in the legend of the graphic above are
2951 instantiated with the types in the following table.
2952 </para>
2953
2954
2955 <informaltable frame="all">
2956
2957 <tgroup cols="3" align="left" colsep="1" rowsep="1">
2958 <colspec colname="c1"/>
2959 <colspec colname="c2"/>
2960 <colspec colname="c3"/>
2961 <thead>
2962 <row>
2963 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
2964 <entry><emphasis>Parameter</emphasis></entry>
2965 <entry><emphasis>Details</emphasis></entry>
2966 </row>
2967 </thead>
2968
2969 <tbody>
2970
2971 <!-- native -->
2972 <row>
2973 <?dbhtml bgcolor="#B0B0B0" ?>
2974 <entry namest="c1" nameend="c3">
2975 n_map
2976 </entry>
2977 </row>
2978
2979 <row>
2980 <entry>
2981 <classname>std::map</classname>
2982 </entry>
2983 <entry namest="c2" nameend="c3"></entry>
2984 </row>
2985
2986 <!-- branch 01 -->
2987 <row>
2988 <?dbhtml bgcolor="#B0B0B0" ?>
2989 <entry namest="c1" nameend="c3">
2990 splay_tree_map
2991 </entry>
2992 </row>
2993
2994 <row>
2995 <entry morerows="1" valign="top">
2996 <classname>tree</classname>
2997 </entry>
2998 <entry>
2999 <classname>Tag</classname>
3000 </entry>
3001 <entry>
3002 <classname>splay_tree_tag</classname>
3003 </entry>
3004 </row>
3005
3006 <row>
3007 <entry>
3008 <classname>Node_Update</classname>
3009 </entry>
3010 <entry>
3011 <classname>null_node_update</classname>
3012 </entry>
3013 </row>
3014
3015
3016 <!-- branch 02 -->
3017 <row>
3018 <?dbhtml bgcolor="#B0B0B0" ?>
3019 <entry namest="c1" nameend="c3">
3020 rb_tree_map
3021 </entry>
3022 </row>
3023
3024 <row>
3025 <entry morerows="1" valign="top">
3026 <classname>tree</classname>
3027 </entry>
3028 <entry>
3029 <classname>Tag</classname>
3030 </entry>
3031 <entry>
3032 <classname>rb_tree_tag</classname>
3033 </entry>
3034 </row>
3035
3036 <row>
3037 <entry>
3038 <classname>Node_Update</classname>
3039 </entry>
3040 <entry>
3041 <classname>null_node_update</classname>
3042 </entry>
3043 </row>
3044
3045
3046 <!-- branch 03 -->
3047 <row>
3048 <?dbhtml bgcolor="#B0B0B0" ?>
3049 <entry namest="c1" nameend="c3">
3050 ov_tree_map
3051 </entry>
3052 </row>
3053
3054 <row>
3055 <entry morerows="1" valign="top">
3056 <classname>tree</classname>
3057 </entry>
3058 <entry>
3059 <classname>Tag</classname>
3060 </entry>
3061 <entry>
3062 <classname>ov_tree_tag</classname>
3063 </entry>
3064 </row>
3065
3066 <row>
3067 <entry>
3068 <classname>Node_Update</classname>
3069 </entry>
3070 <entry>
3071 <classname>null_node_update</classname>
3072 </entry>
3073 </row>
3074
3075
3076 <!-- branch 05 -->
3077 <row>
3078 <?dbhtml bgcolor="#B0B0B0" ?>
3079 <entry namest="c1" nameend="c3">
3080 pat_trie_map
3081 </entry>
3082 </row>
3083
3084 <row>
3085 <entry morerows="1" valign="top">
3086 <classname>tree</classname>
3087 </entry>
3088 <entry>
3089 <classname>Tag</classname>
3090 </entry>
3091 <entry>
3092 <classname>pat_trie_tag</classname>
3093 </entry>
3094 </row>
3095
3096 <row>
3097 <entry>
3098 <classname>Node_Update</classname>
3099 </entry>
3100 <entry>
3101 <classname>null_node_update</classname>
3102 </entry>
3103 </row>
3104
3105 </tbody>
3106 </tgroup>
3107 </informaltable>
3108
3109 </section>
3110
3111 <section xml:id="branch.text_find.observations">
3112 <info><title>
3113 Observations
3114 </title></info>
3115
3116 <para>For this setting, a splay tree (<classname>tree</classname>
3117 with <classname>Tag
3118 </classname> = <classname>splay_tree_tag</classname>) does not do
3119 well. This is possibly due to two reasons:</para>
3120
3121 <orderedlist>
3122 <listitem><para>A splay tree is not guaranteed to be balanced [motwani95random]. If a
3123 splay tree contains n nodes, its average root-leaf
3124 path can be m &gt;&gt; log(n).</para></listitem>
3125 <listitem><para>Assume a specific root-leaf search path has length
3126 m, and the search-target node has distance m'
3127 from the root. A red-black tree will require m + 1
3128 comparisons to find the required node; a splay tree will
3129 require 2 m' comparisons. A splay tree, consequently,
3130 can perform many more comparisons than a red-black tree.</para></listitem>
3131 </orderedlist>
3132 <para>An ordered-vector tree (<classname>tree</classname>
3133 with <classname>Tag</classname> = <classname>ov_tree_tag</classname>), a red-black
3134 tree (<classname>tree</classname>
3135 with <classname>Tag</classname> = <classname>rb_tree_tag</classname>), and the
3136 native red-black tree all share approximately the same
3137 performance.</para>
3138 <para>An ordered-vector tree is slightly slower than red-black
3139 trees, since it requires, in order to find a key, more math
3140 operations than they do. Conversely, an ordered-vector tree
3141 requires far lower space than the others. ([austern00noset], however,
3142 seems to have an implementation that is also faster than a
3143 red-black tree).</para>
3144 <para>A PATRICIA trie (<classname>trie</classname>
3145 with <classname>Tag</classname> = <classname>pat_trie_tag</classname>) has good
3146 look-up performance, due to its large fan-out in this case. In
3147 this setting, a PATRICIA trie has look-up performance comparable
3148 to a hash table (see Hash-Based Text
3149 <classname>find</classname> Timing Test), but it is order
3150 preserving. This is not that surprising, since a large-fan-out
3151 PATRICIA trie works like a hash table with collisions resolved
3152 by a sub-trie. A large-fan-out PATRICIA trie does not do well on
3153 modifications (see Tree-Based and Trie-Based
3154 Text Insert Timing Test). Therefore, it is possibly beneficial in
3155 semi-static settings.</para>
3156 </section>
3157 </section>
3158
3159
3160 <!-- 03 <a href="tree_text_lor_find_find_timing_test"> -->
3161 <section xml:id="performance.branch.text_lor_find">
3162
3163 <info><title>
3164 Text <function>find</function> with Locality-of-Reference
3165 </title></info>
3166 <para></para>
3167
3168 <section xml:id="branch.text_lor_find.info">
3169 <info><title>
3170 Description
3171 </title></info>
3172
3173
3174
3175 <para>This test inserts a number of values with keys from an
3176 arbitrary text ([ wickland96thirty ]) into
3177 a container, then performs a series of finds using
3178 <function>find</function>. It is different than Tree-Based and
3179 Trie-Based Text <function>find</function> Find Timing Test in the
3180 sequence of finds it performs: this test performs multiple
3181 <function>find</function>s on the same key before moving on to the next
3182 key. It measures the average time for <function>find</function> as a
3183 function of the number of values inserted.</para>
3184
3185
3186 <para>
3187 It uses the test file:
3188 <filename>
3189 performance/ext/pb_ds/tree_text_lor_find_timing.cc
3190 </filename>
3191 </para>
3192
3193 <para>The test checks the effect of different underlying
3194 data structures in a locality-of-reference setting.</para>
3195
3196 </section>
3197
3198 <section xml:id="branch.text_lor_find.results">
3199 <info><title>
3200 Results
3201 </title></info>
3202
3203 <para>The graphic immediately below shows the results for the
3204 native tree type and several other tree types.
3205 </para>
3206
3207 <!-- results graphic -->
3208 <informalfigure>
3209 <mediaobject>
3210 <imageobject>
3211 <imagedata align="center" format="PDF" scale="75"
3212 fileref="../images/pbds_tree_text_lor_find_timing_test_local.pdf"/>
3213 </imageobject>
3214 <imageobject>
3215 <imagedata align="center" format="PNG" scale="100"
3216 fileref="../images/pbds_tree_text_lor_find_timing_test_local.png"/>
3217 </imageobject>
3218 </mediaobject>
3219 </informalfigure>
3220
3221 <para>
3222 The abbreviated names in the legend of the graphic above are
3223 instantiated with the types in the following table.
3224 </para>
3225
3226
3227 <informaltable frame="all">
3228
3229 <tgroup cols="3" align="left" colsep="1" rowsep="1">
3230 <colspec colname="c1"/>
3231 <colspec colname="c2"/>
3232 <colspec colname="c3"/>
3233 <thead>
3234 <row>
3235 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
3236 <entry><emphasis>Parameter</emphasis></entry>
3237 <entry><emphasis>Details</emphasis></entry>
3238 </row>
3239 </thead>
3240
3241 <tbody>
3242
3243 <!-- native -->
3244 <row>
3245 <?dbhtml bgcolor="#B0B0B0" ?>
3246 <entry namest="c1" nameend="c3">
3247 n_map
3248 </entry>
3249 </row>
3250
3251 <row>
3252 <entry>
3253 <classname>std::map</classname>
3254 </entry>
3255 <entry namest="c2" nameend="c3"></entry>
3256 </row>
3257
3258 <!-- branch 01 -->
3259 <row>
3260 <?dbhtml bgcolor="#B0B0B0" ?>
3261 <entry namest="c1" nameend="c3">
3262 splay_tree_map
3263 </entry>
3264 </row>
3265
3266 <row>
3267 <entry morerows="1" valign="top">
3268 <classname>tree</classname>
3269 </entry>
3270 <entry>
3271 <classname>Tag</classname>
3272 </entry>
3273 <entry>
3274 <classname>splay_tree_tag</classname>
3275 </entry>
3276 </row>
3277
3278 <row>
3279 <entry>
3280 <classname>Node_Update</classname>
3281 </entry>
3282 <entry>
3283 <classname>null_node_update</classname>
3284 </entry>
3285 </row>
3286
3287
3288 <!-- branch 02 -->
3289 <row>
3290 <?dbhtml bgcolor="#B0B0B0" ?>
3291 <entry namest="c1" nameend="c3">
3292 rb_tree_map
3293 </entry>
3294 </row>
3295
3296 <row>
3297 <entry morerows="1" valign="top">
3298 <classname>tree</classname>
3299 </entry>
3300 <entry>
3301 <classname>Tag</classname>
3302 </entry>
3303 <entry>
3304 <classname>rb_tree_tag</classname>
3305 </entry>
3306 </row>
3307
3308 <row>
3309 <entry>
3310 <classname>Node_Update</classname>
3311 </entry>
3312 <entry>
3313 <classname>null_node_update</classname>
3314 </entry>
3315 </row>
3316
3317
3318 <!-- branch 03 -->
3319 <row>
3320 <?dbhtml bgcolor="#B0B0B0" ?>
3321 <entry namest="c1" nameend="c3">
3322 ov_tree_map
3323 </entry>
3324 </row>
3325
3326 <row>
3327 <entry morerows="1" valign="top">
3328 <classname>tree</classname>
3329 </entry>
3330 <entry>
3331 <classname>Tag</classname>
3332 </entry>
3333 <entry>
3334 <classname>ov_tree_tag</classname>
3335 </entry>
3336 </row>
3337
3338 <row>
3339 <entry>
3340 <classname>Node_Update</classname>
3341 </entry>
3342 <entry>
3343 <classname>null_node_update</classname>
3344 </entry>
3345 </row>
3346
3347
3348 <!-- branch 05 -->
3349 <row>
3350 <?dbhtml bgcolor="#B0B0B0" ?>
3351 <entry namest="c1" nameend="c3">
3352 pat_trie_map
3353 </entry>
3354 </row>
3355
3356 <row>
3357 <entry morerows="1" valign="top">
3358 <classname>tree</classname>
3359 </entry>
3360 <entry>
3361 <classname>Tag</classname>
3362 </entry>
3363 <entry>
3364 <classname>pat_trie_tag</classname>
3365 </entry>
3366 </row>
3367
3368 <row>
3369 <entry>
3370 <classname>Node_Update</classname>
3371 </entry>
3372 <entry>
3373 <classname>null_node_update</classname>
3374 </entry>
3375 </row>
3376
3377 </tbody>
3378 </tgroup>
3379 </informaltable>
3380
3381 </section>
3382
3383 <section xml:id="branch.text_lor_find.observations">
3384 <info><title>
3385 Observations
3386 </title></info>
3387
3388 <para>For this setting, an ordered-vector tree
3389 (<classname>tree</classname> with <classname>Tag</classname>
3390 = <classname>ov_tree_tag</classname>), a red-black tree
3391 (<classname>tree</classname> with <classname>Tag</classname>
3392 = <classname>rb_tree_tag</classname>), and the native red-black
3393 tree all share approximately the same performance.</para>
3394 <para>A splay tree (<classname>tree</classname>
3395 with <classname>Tag</classname> = <classname>splay_tree_tag</classname>) does
3396 much better, since each (successful) find "bubbles" the
3397 corresponding node to the root of the tree.</para>
3398
3399 </section>
3400 </section>
3401
3402 <!-- 04 <a href="tree_split_join_timing_test"> -->
3403 <section xml:id="performance.branch.split_join">
3404
3405 <info><title>
3406 <function>split</function> and <function>join</function>
3407 </title></info>
3408 <para></para>
3409
3410 <section xml:id="branch.split_join.info">
3411 <info><title>
3412 Description
3413 </title></info>
3414
3415
3416 <para>This test a container, inserts into a number of values, splits
3417 the container at the median, and joins the two containers. (If the
3418 containers are one of this library's trees,
3419 it splits and joins with the <function>split</function> and
3420 <function>join</function> method; otherwise, it uses the <function>erase</function> and
3421 <function>insert</function> methods.) It measures the time for splitting
3422 and joining the containers as a function of the number of
3423 values inserted.</para>
3424
3425 <para>
3426 It uses the test file:
3427 <filename>
3428 performance/ext/pb_ds/tree_split_join_timing.cc
3429 </filename>
3430 </para>
3431
3432
3433 <para>The test checks the performance difference of <function>join</function>
3434 as opposed to a sequence of <function>insert</function> operations; by
3435 implication, this test checks the most efficient way to erase a
3436 sub-sequence from a tree-like-based container, since this can
3437 always be performed by a small sequence of splits and joins.
3438 </para>
3439 </section>
3440
3441 <section xml:id="branch.split_join.results">
3442 <info><title>
3443 Results
3444 </title></info>
3445
3446 <para>The graphic immediately below shows the results for the
3447 native tree type and several other tree types.
3448 </para>
3449
3450 <!-- results graphic -->
3451 <informalfigure>
3452 <mediaobject>
3453 <imageobject>
3454 <imagedata align="center" format="PDF" scale="75"
3455 fileref="../images/pbds_tree_split_join_timing_test_local.pdf"/>
3456 </imageobject>
3457 <imageobject>
3458 <imagedata align="center" format="PNG" scale="100"
3459 fileref="../images/pbds_tree_split_join_timing_test_local.png"/>
3460 </imageobject>
3461 </mediaobject>
3462 </informalfigure>
3463
3464 <para>
3465 The abbreviated names in the legend of the graphic above are
3466 instantiated with the types in the following table.
3467 </para>
3468
3469
3470 <informaltable frame="all">
3471
3472 <tgroup cols="3" align="left" colsep="1" rowsep="1">
3473 <colspec colname="c1"/>
3474 <colspec colname="c2"/>
3475 <colspec colname="c3"/>
3476 <thead>
3477 <row>
3478 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
3479 <entry><emphasis>Parameter</emphasis></entry>
3480 <entry><emphasis>Details</emphasis></entry>
3481 </row>
3482 </thead>
3483
3484 <tbody>
3485
3486 <!-- native -->
3487 <row>
3488 <?dbhtml bgcolor="#B0B0B0" ?>
3489 <entry namest="c1" nameend="c3">
3490 n_set
3491 </entry>
3492 </row>
3493
3494 <row>
3495 <entry>
3496 <classname>std::set</classname>
3497 </entry>
3498 <entry namest="c2" nameend="c3"></entry>
3499 </row>
3500
3501 <!-- branch 01 -->
3502 <row>
3503 <?dbhtml bgcolor="#B0B0B0" ?>
3504 <entry namest="c1" nameend="c3">
3505 splay_tree_set
3506 </entry>
3507 </row>
3508
3509 <row>
3510 <entry morerows="1" valign="top">
3511 <classname>tree</classname>
3512 </entry>
3513 <entry>
3514 <classname>Tag</classname>
3515 </entry>
3516 <entry>
3517 <classname>splay_tree_tag</classname>
3518 </entry>
3519 </row>
3520
3521 <row>
3522 <entry>
3523 <classname>Node_Update</classname>
3524 </entry>
3525 <entry>
3526 <classname>null_node_update</classname>
3527 </entry>
3528 </row>
3529
3530
3531 <!-- branch 02 -->
3532 <row>
3533 <?dbhtml bgcolor="#B0B0B0" ?>
3534 <entry namest="c1" nameend="c3">
3535 rb_tree_set
3536 </entry>
3537 </row>
3538
3539 <row>
3540 <entry morerows="1" valign="top">
3541 <classname>tree</classname>
3542 </entry>
3543 <entry>
3544 <classname>Tag</classname>
3545 </entry>
3546 <entry>
3547 <classname>rb_tree_tag</classname>
3548 </entry>
3549 </row>
3550
3551 <row>
3552 <entry>
3553 <classname>Node_Update</classname>
3554 </entry>
3555 <entry>
3556 <classname>null_node_update</classname>
3557 </entry>
3558 </row>
3559
3560
3561 <!-- branch 03 -->
3562 <row>
3563 <?dbhtml bgcolor="#B0B0B0" ?>
3564 <entry namest="c1" nameend="c3">
3565 ov_tree_set
3566 </entry>
3567 </row>
3568
3569 <row>
3570 <entry morerows="1" valign="top">
3571 <classname>tree</classname>
3572 </entry>
3573 <entry>
3574 <classname>Tag</classname>
3575 </entry>
3576 <entry>
3577 <classname>ov_tree_tag</classname>
3578 </entry>
3579 </row>
3580
3581 <row>
3582 <entry>
3583 <classname>Node_Update</classname>
3584 </entry>
3585 <entry>
3586 <classname>null_node_update</classname>
3587 </entry>
3588 </row>
3589
3590
3591 <!-- branch 05 -->
3592 <row>
3593 <?dbhtml bgcolor="#B0B0B0" ?>
3594 <entry namest="c1" nameend="c3">
3595 pat_trie_map
3596 </entry>
3597 </row>
3598
3599 <row>
3600 <entry morerows="1" valign="top">
3601 <classname>tree</classname>
3602 </entry>
3603 <entry>
3604 <classname>Tag</classname>
3605 </entry>
3606 <entry>
3607 <classname>pat_trie_tag</classname>
3608 </entry>
3609 </row>
3610
3611 <row>
3612 <entry>
3613 <classname>Node_Update</classname>
3614 </entry>
3615 <entry>
3616 <classname>null_node_update</classname>
3617 </entry>
3618 </row>
3619
3620 </tbody>
3621 </tgroup>
3622 </informaltable>
3623
3624 </section>
3625
3626 <section xml:id="branch.split_join.observations">
3627 <info><title>
3628 Observations
3629 </title></info>
3630
3631 <para>In this test, the native red-black trees must be split and
3632 joined externally, through a sequence of <function>erase</function> and
3633 <function>insert</function> operations. This is clearly
3634 super-linear, and it is not that surprising that the cost is
3635 high.</para>
3636 <para>This library's tree-based containers use in this test the
3637 <function>split</function> and <function>join</function> methods,
3638 which have lower complexity: the <function>join</function> method
3639 of a splay tree (<classname>tree</classname>
3640 with <classname>Tag </classname>
3641 = <classname>splay_tree_tag</classname>) is quadratic in the
3642 length of the longest root-leaf path, and linear in the total
3643 number of elements; the <function>join</function> method of a
3644 red-black tree (<classname>tree</classname>
3645 with <classname>Tag </classname>
3646 = <classname>rb_tree_tag</classname>) or an ordered-vector tree
3647 (<classname>tree</classname> with <classname>Tag </classname>
3648 = <classname>ov_tree_tag</classname>) is linear in the number of
3649 elements.</para>
3650
3651 <para>Asides from orders of growth, this library's trees access their
3652 allocator very little in these operations, and some of them do not
3653 access it at all. This leads to lower constants in their
3654 complexity, and, for some containers, to exception-free splits and
3655 joins (which can be determined
3656 via <classname>container_traits</classname>).</para>
3657
3658 <para>It is important to note that <function>split</function> and
3659 <function>join</function> are not esoteric methods - they are the most
3660 efficient means of erasing a contiguous range of values from a
3661 tree based container.</para>
3662 </section>
3663 </section>
3664
3665 <!-- 05 <a href="tree_order_statistics_timing_test"> -->
3666 <section xml:id="performance.branch.order_statistics">
3667
3668 <info><title>
3669 Order-Statistics
3670 </title></info>
3671 <para></para>
3672
3673 <section xml:id="branch.order_statistics.info">
3674 <info><title>
3675 Description
3676 </title></info>
3677
3678 <para>This test creates a container, inserts random integers into the
3679 the container, and then checks the order-statistics of the
3680 container's values. (If the container is one of this
3681 library's trees, it does this with
3682 the <function>order_of_key</function> method of
3683 <classname>tree_order_statistics_node_update</classname>
3684 ; otherwise, it uses the <function>find</function> method and
3685 <function>std::distance</function>.) It measures the average
3686 time for such queries as a function of the number of values
3687 inserted.</para>
3688
3689 <para>
3690 It uses the test file:
3691 <filename>
3692 performance/ext/pb_ds/tree_order_statistics_timing.cc
3693 </filename>
3694 </para>
3695
3696 <para>The test checks the performance difference of policies based
3697 on node-invariant as opposed to a external functions.</para>
3698
3699 </section>
3700
3701 <section xml:id="branch.order_statistics.results">
3702 <info><title>
3703 Results
3704 </title></info>
3705
3706 <para>The graphic immediately below shows the results for the
3707 native tree type and several other tree types.
3708 </para>
3709
3710 <!-- results graphic -->
3711 <informalfigure>
3712 <mediaobject>
3713 <imageobject>
3714 <imagedata align="center" format="PDF" scale="75"
3715 fileref="../images/pbds_tree_order_statistics_timing_test_local.pdf"/>
3716 </imageobject>
3717 <imageobject>
3718 <imagedata align="center" format="PNG" scale="100"
3719 fileref="../images/pbds_tree_order_statistics_timing_test_local.png"/>
3720 </imageobject>
3721 </mediaobject>
3722 </informalfigure>
3723
3724 <para>
3725 The abbreviated names in the legend of the graphic above are
3726 instantiated with the types in the following table.
3727 </para>
3728
3729
3730 <informaltable frame="all">
3731
3732 <tgroup cols="3" align="left" colsep="1" rowsep="1">
3733 <colspec colname="c1"/>
3734 <colspec colname="c2"/>
3735 <colspec colname="c3"/>
3736 <thead>
3737 <row>
3738 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
3739 <entry><emphasis>Parameter</emphasis></entry>
3740 <entry><emphasis>Details</emphasis></entry>
3741 </row>
3742 </thead>
3743
3744 <tbody>
3745
3746 <!-- native -->
3747 <row>
3748 <?dbhtml bgcolor="#B0B0B0" ?>
3749 <entry namest="c1" nameend="c3">
3750 n_set
3751 </entry>
3752 </row>
3753
3754 <row>
3755 <entry>
3756 <classname>std::set</classname>
3757 </entry>
3758 <entry namest="c2" nameend="c3"></entry>
3759 </row>
3760
3761 <!-- branch 01 -->
3762 <row>
3763 <?dbhtml bgcolor="#B0B0B0" ?>
3764 <entry namest="c1" nameend="c3">
3765 splay_tree_ost_set
3766 </entry>
3767 </row>
3768
3769 <row>
3770 <entry morerows="1" valign="top">
3771 <classname>tree</classname>
3772 </entry>
3773 <entry>
3774 <classname>Tag</classname>
3775 </entry>
3776 <entry>
3777 <classname>splay_tree_tag</classname>
3778 </entry>
3779 </row>
3780
3781 <row>
3782 <entry>
3783 <classname>Node_Update</classname>
3784 </entry>
3785 <entry>
3786 <classname>tree_order_statistics_node_update</classname>
3787 </entry>
3788 </row>
3789
3790
3791 <!-- branch 02 -->
3792 <row>
3793 <?dbhtml bgcolor="#B0B0B0" ?>
3794 <entry namest="c1" nameend="c3">
3795 rb_tree_ost_set
3796 </entry>
3797 </row>
3798
3799 <row>
3800 <entry morerows="1" valign="top">
3801 <classname>tree</classname>
3802 </entry>
3803 <entry>
3804 <classname>Tag</classname>
3805 </entry>
3806 <entry>
3807 <classname>rb_tree_tag</classname>
3808 </entry>
3809 </row>
3810
3811 <row>
3812 <entry>
3813 <classname>Node_Update</classname>
3814 </entry>
3815 <entry>
3816 <classname>tree_order_statistics_node_update</classname>
3817 </entry>
3818 </row>
3819
3820
3821 </tbody>
3822 </tgroup>
3823 </informaltable>
3824
3825 </section>
3826
3827 <section xml:id="branch.order_statistics.observations">
3828 <info><title>
3829 Observations
3830 </title></info>
3831 <para>In this test, the native red-black tree can support
3832 order-statistics queries only externally, by performing a
3833 <classname>find</classname> (alternatively, <classname>lower_bound</classname> or
3834 <classname>upper_bound</classname> ) and then using <classname>std::distance</classname> .
3835 This is clearly linear, and it is not that surprising that the
3836 cost is high.</para>
3837 <para>This library's tree-based containers use in this test the
3838 <classname>order_of_key</classname> method of <classname>tree_order_statistics_node_update</classname>.
3839 This method has only linear complexity in the length of the
3840 root-node path. Unfortunately, the average path of a splay tree
3841 (<classname>tree</classname>
3842 with <classname>Tag =</classname> <classname>splay_tree_tag</classname> ) can
3843 be higher than logarithmic; the longest path of a red-black
3844 tree (<classname>tree</classname>
3845 with <classname>Tag =</classname> <classname>rb_tree_tag</classname> ) is
3846 logarithmic in the number of elements. Consequently, the splay
3847 tree has worse performance than the red-black tree.</para>
3848 </section>
3849 </section>
3850
3851 </section> <!-- branch -->
3852
3853 <section xml:id="performance.multimap">
3854 <info><title>Multimap</title></info>
3855 <para></para>
3856
3857
3858 <!-- 01 <a href="multimap_text_find_timing_test_small"> -->
3859 <section xml:id="performance.multimap.text_find_small">
3860 <info><title>
3861 Text <function>find</function> with Small Secondary-to-Primary Key Ratios
3862 </title></info>
3863 <para></para>
3864
3865 <section xml:id="multimap.text_find_small.info">
3866 <info><title>
3867 Description
3868 </title></info>
3869
3870 <para>This test inserts a number of pairs into a container. The
3871 first item of each pair is a string from an arbitrary text
3872 [wickland96thirty], and
3873 the second is a uniform i.i.d.integer. The container is a
3874 "multimap" - it considers the first member of each pair as a
3875 primary key, and the second member of each pair as a secondary
3876 key (see Motivation::Associative
3877 Containers::Alternative to Multiple Equivalent Keys). There
3878 are 400 distinct primary keys, and the ratio of secondary keys
3879 to primary keys ranges from 1 to 5.</para>
3880 <para>The test measures the average find-time as a function of the
3881 number of values inserted. For this library's containers, it
3882 finds the secondary key from a container obtained from finding
3883 a primary key. For the native multimaps, it searches a range
3884 obtained using <classname>std::equal_range</classname> on a primary key.</para>
3885
3886 <para>
3887 It uses the test file:
3888 <filename>
3889 performance/ext/pb_ds/multimap_text_find_timing_small.cc
3890 </filename>
3891 </para>
3892
3893 <para>The test checks the find-time scalability of different
3894 "multimap" designs.</para>
3895
3896 </section>
3897
3898 <section xml:id="multimap.text_find_small.results">
3899 <info><title>
3900 Results
3901 </title></info>
3902
3903 <para>The graphic below show the results for "multimaps" which
3904 use a tree-based container for primary keys.
3905 </para>
3906
3907 <!-- results graphic -->
3908 <informalfigure>
3909 <mediaobject>
3910 <imageobject>
3911 <imagedata align="center" format="PNG" scale="100"
3912 fileref="../images/pbds_multimap_text_find_timing_test_small_s2p_tree_local.png"/>
3913 </imageobject>
3914 <imageobject>
3915 <imagedata align="center" format="PDF" scale="33"
3916 fileref="../images/pbds_multimap_text_find_timing_test_small_s2p_tree_local.pdf"/>
3917 </imageobject>
3918 </mediaobject>
3919 </informalfigure>
3920
3921 <para>
3922 The abbreviated names in the legend of the graphic above are
3923 instantiated with the types in the following table.
3924 </para>
3925
3926
3927 <informaltable frame="all">
3928
3929 <tgroup cols="7" align="left" colsep="1" rowsep="1">
3930 <colspec colname="c1"/>
3931 <colspec colname="c2"/>
3932 <colspec colname="c3"/>
3933 <colspec colname="c4"/>
3934 <colspec colname="c5"/>
3935 <colspec colname="c6"/>
3936 <colspec colname="c7"/>
3937 <thead>
3938 <row>
3939 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
3940 <entry><emphasis>Parameter</emphasis></entry>
3941 <entry><emphasis>Details</emphasis></entry>
3942 <entry><emphasis>Parameter</emphasis></entry>
3943 <entry><emphasis>Details</emphasis></entry>
3944 <entry><emphasis>Parameter</emphasis></entry>
3945 <entry><emphasis>Details</emphasis></entry>
3946 </row>
3947 </thead>
3948
3949 <tbody>
3950
3951 <!-- native -->
3952 <row>
3953 <?dbhtml bgcolor="#B0B0B0" ?>
3954 <entry namest="c1" nameend="c7">
3955 n_mmap
3956 </entry>
3957 </row>
3958
3959 <row>
3960 <entry>
3961 <classname>std::multimap</classname>
3962 </entry>
3963 <entry namest="c2" nameend="c7"></entry>
3964 </row>
3965
3966 <!-- multimap 01 -->
3967 <row>
3968 <?dbhtml bgcolor="#B0B0B0" ?>
3969 <entry namest="c1" nameend="c7">
3970 rb_tree_mmap_lu_mtf_set
3971 </entry>
3972 </row>
3973
3974 <row>
3975 <entry morerows="2" valign="top">
3976 <classname>tree</classname>
3977 </entry>
3978 <entry>
3979 <classname>Tag</classname>
3980 </entry>
3981 <entry>
3982 <classname>rb_tree_tag</classname>
3983 </entry>
3984 <entry namest="c4" nameend="c7"></entry>
3985 </row>
3986
3987 <row>
3988 <entry>
3989 <classname>Node_Update</classname>
3990 </entry>
3991 <entry>
3992 <classname>null_node_update</classname>
3993 </entry>
3994 <entry namest="c4" nameend="c7"></entry>
3995 </row>
3996 <row>
3997 <entry>
3998 <classname>Mapped</classname>
3999 </entry>
4000 <entry>
4001 <classname>list_update</classname>
4002 </entry>
4003 <entry>
4004 <classname>Update_Policy</classname>
4005 </entry>
4006 <entry>
4007 <classname>lu_move_to_front_policy</classname>
4008 </entry>
4009 <entry namest="c6" nameend="c7"></entry>
4010 </row>
4011
4012 <!-- multimap 02 -->
4013 <row>
4014 <?dbhtml bgcolor="#B0B0B0" ?>
4015 <entry namest="c1" nameend="c7">
4016 rb_tree_mmap_cc_hash_mask_exp_nea_lc_1div8_1div2_nsth_set
4017 </entry>
4018 </row>
4019
4020 <row>
4021 <entry morerows="4" valign="top">
4022 <classname>tree</classname>
4023 </entry>
4024 <entry>
4025 <classname>Tag</classname>
4026 </entry>
4027 <entry>
4028 <classname>rb_tree_tag</classname>
4029 </entry>
4030 <entry namest="c4" nameend="c7"></entry>
4031 </row>
4032
4033 <row>
4034 <entry>
4035 <classname>Node_Update</classname>
4036 </entry>
4037 <entry>
4038 <classname>null_node_update</classname>
4039 </entry>
4040 <entry namest="c4" nameend="c7"></entry>
4041 </row>
4042
4043 <row>
4044 <entry morerows="2" valign="top">
4045 <classname>Mapped</classname>
4046 </entry>
4047 <entry morerows="2" valign="top">
4048 <classname>cc_hash_table</classname>
4049 </entry>
4050 <entry>
4051 <classname>Comb_Hash_Fn</classname>
4052 </entry>
4053 <entry>
4054 <classname>direct_mask_range_hashing</classname>
4055 </entry>
4056 <entry namest="c6" nameend="c7"></entry>
4057 </row>
4058
4059 <row>
4060 <entry morerows="1" valign="top">
4061 <classname>Resize_Policy</classname>
4062 </entry>
4063 <entry morerows="1" valign="top">
4064 <classname>hash_standard_resize_policy</classname>
4065 </entry>
4066 <entry>
4067 <classname>Size_Policy</classname>
4068 </entry>
4069 <entry>
4070 <classname>hash_exponential_size_policy</classname>
4071 </entry>
4072 </row>
4073
4074 <row>
4075 <entry valign="top">
4076 <classname>Trigger_Policy</classname>
4077 </entry>
4078 <entry>
4079 <classname>hash_load_check_resize_trigger</classname> with
4080 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
4081 </entry>
4082 </row>
4083
4084 </tbody>
4085 </tgroup>
4086 </informaltable>
4087
4088
4089 <para>The graphic below show the results for "multimaps" which
4090 use a hash-based container for primary keys.
4091 </para>
4092
4093 <!-- results graphic -->
4094 <informalfigure>
4095 <mediaobject>
4096 <imageobject>
4097 <imagedata align="center" format="PNG" scale="100"
4098 fileref="../images/pbds_multimap_text_find_timing_test_small_s2p_hash_local.png"/>
4099 </imageobject>
4100 <imageobject>
4101 <imagedata align="center" format="PDF" scale="33"
4102 fileref="../images/pbds_multimap_text_find_timing_test_small_s2p_hash_local.pdf"/>
4103 </imageobject>
4104 </mediaobject>
4105 </informalfigure>
4106
4107 <para>
4108 The abbreviated names in the legend of the graphic above are
4109 instantiated with the types in the following table.
4110 </para>
4111
4112 <informaltable frame="all">
4113
4114 <tgroup cols="7" align="left" colsep="1" rowsep="1">
4115 <colspec colname="c1"/>
4116 <colspec colname="c2"/>
4117 <colspec colname="c3"/>
4118 <colspec colname="c4"/>
4119 <colspec colname="c5"/>
4120 <colspec colname="c6"/>
4121 <colspec colname="c7"/>
4122 <thead>
4123 <row>
4124 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
4125 <entry><emphasis>Parameter</emphasis></entry>
4126 <entry><emphasis>Details</emphasis></entry>
4127 <entry><emphasis>Parameter</emphasis></entry>
4128 <entry><emphasis>Details</emphasis></entry>
4129 <entry><emphasis>Parameter</emphasis></entry>
4130 <entry><emphasis>Details</emphasis></entry>
4131 </row>
4132 </thead>
4133
4134 <tbody>
4135
4136 <!-- native -->
4137 <row>
4138 <?dbhtml bgcolor="#B0B0B0" ?>
4139 <entry namest="c1" nameend="c7">
4140 n_hash_mmap
4141 </entry>
4142 </row>
4143
4144 <row>
4145 <entry>
4146 <classname>std::tr1::unordered_multimap</classname>
4147 </entry>
4148 <entry namest="c2" nameend="c7"></entry>
4149 </row>
4150
4151 <!-- multimap 01 -->
4152 <row>
4153 <?dbhtml bgcolor="#B0B0B0" ?>
4154 <entry namest="c1" nameend="c7">
4155 rb_tree_mmap_lu_mtf_set
4156 </entry>
4157 </row>
4158
4159 <row>
4160 <entry morerows="3" valign="top">
4161 <classname>
4162 cc_hash_table
4163 </classname>
4164 </entry>
4165 <entry>
4166 <classname>Comb_Hash_Fn</classname>
4167 </entry>
4168 <entry>
4169 <classname>direct_mask_range_hashing</classname>
4170 </entry>
4171 <entry namest="c4" nameend="c7"></entry>
4172 </row>
4173 <row>
4174 <entry morerows="1" valign="top">
4175 <classname>Resize_Policy</classname>
4176 </entry>
4177 <entry morerows="1" valign="top">
4178 <classname>hash_standard_resize_policy</classname>
4179 </entry>
4180 <entry>
4181 <classname>Size_Policy</classname>
4182 </entry>
4183 <entry>
4184 <classname>hash_exponential_size_policy</classname>
4185 </entry>
4186 <entry namest="c6" nameend="c7"></entry>
4187 </row>
4188
4189 <row>
4190 <entry valign="top">
4191 <classname>Trigger_Policy</classname>
4192 </entry>
4193 <entry>
4194 <classname>hash_load_check_resize_trigger</classname> with
4195 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
4196 </entry>
4197 <entry namest="c6" nameend="c7"></entry>
4198 </row>
4199
4200 <row>
4201 <entry>
4202 <classname>Mapped</classname>
4203 </entry>
4204 <entry>
4205 <classname>list_update</classname>
4206 </entry>
4207 <entry>
4208 <classname>Update_Policy</classname>
4209 </entry>
4210 <entry>
4211 <classname>lu_move_to_front_policy</classname>
4212 </entry>
4213 <entry namest="c6" nameend="c7"></entry>
4214 </row>
4215
4216 <!-- multimap 02 -->
4217 <row>
4218 <?dbhtml bgcolor="#B0B0B0" ?>
4219 <entry namest="c1" nameend="c7">
4220 rb_tree_mmap_cc_hash_mask_exp_nea_lc_1div8_1div2_nsth_set
4221 </entry>
4222 </row>
4223
4224 <row>
4225 <entry morerows="5" valign="top">
4226 <classname>
4227 cc_hash_table
4228 </classname>
4229 </entry>
4230 <entry>
4231 <classname>Comb_Hash_Fn</classname>
4232 </entry>
4233 <entry>
4234 <classname>direct_mask_range_hashing</classname>
4235 </entry>
4236 <entry namest="c4" nameend="c7"></entry>
4237 </row>
4238 <row>
4239 <entry morerows="1" valign="top">
4240 <classname>Resize_Policy</classname>
4241 </entry>
4242 <entry morerows="1" valign="top">
4243 <classname>hash_standard_resize_policy</classname>
4244 </entry>
4245 <entry>
4246 <classname>Size_Policy</classname>
4247 </entry>
4248 <entry>
4249 <classname>hash_exponential_size_policy</classname>
4250 </entry>
4251 <entry namest="c6" nameend="c7"></entry>
4252 </row>
4253
4254 <row>
4255 <entry valign="top">
4256 <classname>Trigger_Policy</classname>
4257 </entry>
4258 <entry>
4259 <classname>hash_load_check_resize_trigger</classname> with
4260 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
4261 </entry>
4262 <entry namest="c6" nameend="c7"></entry>
4263 </row>
4264
4265 <row>
4266 <entry morerows="2" valign="top">
4267 <classname>Mapped</classname>
4268 </entry>
4269 <entry morerows="2" valign="top">
4270 <classname>cc_hash_table</classname>
4271 </entry>
4272 <entry>
4273 <classname>Comb_Hash_Fn</classname>
4274 </entry>
4275 <entry>
4276 <classname>direct_mask_range_hashing</classname>
4277 </entry>
4278 <entry namest="c6" nameend="c7"></entry>
4279 </row>
4280
4281 <row>
4282 <entry morerows="1" valign="top">
4283 <classname>Resize_Policy</classname>
4284 </entry>
4285 <entry morerows="1" valign="top">
4286 <classname>hash_standard_resize_policy</classname>
4287 </entry>
4288 <entry>
4289 <classname>Size_Policy</classname>
4290 </entry>
4291 <entry>
4292 <classname>hash_exponential_size_policy</classname>
4293 </entry>
4294 </row>
4295
4296 <row>
4297 <entry valign="top">
4298 <classname>Trigger_Policy</classname>
4299 </entry>
4300 <entry>
4301 <classname>hash_load_check_resize_trigger</classname> with
4302 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
4303 </entry>
4304 </row>
4305
4306 </tbody>
4307 </tgroup>
4308 </informaltable>
4309
4310 </section>
4311
4312 <section xml:id="multimap.text_find_small.observations">
4313 <info><title>
4314 Observations
4315 </title></info>
4316
4317 <para>See Observations::Mapping-Semantics
4318 Considerations.</para>
4319
4320 </section>
4321
4322 </section>
4323
4324 <!-- 02 <a href="multimap_text_find_timing_test_large"> -->
4325 <section xml:id="performance.multimap.text_find_large">
4326 <info><title>
4327 Text <function>find</function> with Large Secondary-to-Primary Key Ratios
4328 </title></info>
4329 <para></para>
4330
4331 <section xml:id="multimap.text_find_large.info">
4332 <info><title>
4333 Description
4334 </title></info>
4335
4336 <para>This test inserts a number of pairs into a container. The
4337 first item of each pair is a string from an arbitrary text
4338 [wickland96thirty], and
4339 the second is a uniform integer. The container is a
4340 "multimap" - it considers the first member of each pair as a
4341 primary key, and the second member of each pair as a secondary
4342 key. There
4343 are 400 distinct primary keys, and the ratio of secondary keys
4344 to primary keys ranges from 1 to 5.</para>
4345 <para>The test measures the average find-time as a function of the
4346 number of values inserted. For this library's containers, it
4347 finds the secondary key from a container obtained from finding
4348 a primary key. For the native multimaps, it searches a range
4349 obtained using <classname>std::equal_range</classname> on a primary key.</para>
4350
4351 <para>
4352 It uses the test file:
4353 <filename>
4354 performance/ext/pb_ds/multimap_text_find_timing_large.cc
4355 </filename>
4356 </para>
4357
4358 <para>The test checks the find-time scalability of different
4359 "multimap" designs.</para>
4360
4361 </section>
4362
4363 <section xml:id="multimap.text_find_large.results">
4364 <info><title>
4365 Results
4366 </title></info>
4367
4368 <para>The graphic below show the results for "multimaps" which
4369 use a tree-based container for primary keys.
4370 </para>
4371
4372 <!-- results graphic -->
4373 <informalfigure>
4374 <mediaobject>
4375 <imageobject>
4376 <imagedata align="center" format="PNG" scale="100"
4377 fileref="../images/pbds_multimap_text_find_timing_test_large_s2p_tree_local.png"/>
4378 </imageobject>
4379 <imageobject>
4380 <imagedata align="center" format="PDF" scale="33"
4381 fileref="../images/pbds_multimap_text_find_timing_test_large_s2p_tree_local.pdf"/>
4382 </imageobject>
4383 </mediaobject>
4384 </informalfigure>
4385
4386 <para>
4387 The abbreviated names in the legend of the graphic above are
4388 instantiated with the types in the following table.
4389 </para>
4390
4391
4392 <informaltable frame="all">
4393
4394 <tgroup cols="7" align="left" colsep="1" rowsep="1">
4395 <colspec colname="c1"/>
4396 <colspec colname="c2"/>
4397 <colspec colname="c3"/>
4398 <colspec colname="c4"/>
4399 <colspec colname="c5"/>
4400 <colspec colname="c6"/>
4401 <colspec colname="c7"/>
4402 <thead>
4403 <row>
4404 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
4405 <entry><emphasis>Parameter</emphasis></entry>
4406 <entry><emphasis>Details</emphasis></entry>
4407 <entry><emphasis>Parameter</emphasis></entry>
4408 <entry><emphasis>Details</emphasis></entry>
4409 <entry><emphasis>Parameter</emphasis></entry>
4410 <entry><emphasis>Details</emphasis></entry>
4411 </row>
4412 </thead>
4413
4414 <tbody>
4415
4416 <!-- native -->
4417 <row>
4418 <?dbhtml bgcolor="#B0B0B0" ?>
4419 <entry namest="c1" nameend="c7">
4420 n_mmap
4421 </entry>
4422 </row>
4423
4424 <row>
4425 <entry>
4426 <classname>std::multimap</classname>
4427 </entry>
4428 <entry namest="c2" nameend="c7"></entry>
4429 </row>
4430
4431 <!-- multimap 01 -->
4432 <row>
4433 <?dbhtml bgcolor="#B0B0B0" ?>
4434 <entry namest="c1" nameend="c7">
4435 rb_tree_mmap_lu_mtf_set
4436 </entry>
4437 </row>
4438
4439 <row>
4440 <entry morerows="2" valign="top">
4441 <classname>tree</classname>
4442 </entry>
4443 <entry>
4444 <classname>Tag</classname>
4445 </entry>
4446 <entry>
4447 <classname>rb_tree_tag</classname>
4448 </entry>
4449 <entry namest="c4" nameend="c7"></entry>
4450 </row>
4451
4452 <row>
4453 <entry>
4454 <classname>Node_Update</classname>
4455 </entry>
4456 <entry>
4457 <classname>null_node_update</classname>
4458 </entry>
4459 <entry namest="c4" nameend="c7"></entry>
4460 </row>
4461 <row>
4462 <entry>
4463 <classname>Mapped</classname>
4464 </entry>
4465 <entry>
4466 <classname>list_update</classname>
4467 </entry>
4468 <entry>
4469 <classname>Update_Policy</classname>
4470 </entry>
4471 <entry>
4472 <classname>lu_move_to_front_policy</classname>
4473 </entry>
4474 <entry namest="c6" nameend="c7"></entry>
4475 </row>
4476
4477 <!-- multimap 02 -->
4478 <row>
4479 <?dbhtml bgcolor="#B0B0B0" ?>
4480 <entry namest="c1" nameend="c7">
4481 rb_tree_mmap_cc_hash_mask_exp_nea_lc_1div8_1div2_nsth_set
4482 </entry>
4483 </row>
4484
4485 <row>
4486 <entry morerows="4" valign="top">
4487 <classname>tree</classname>
4488 </entry>
4489 <entry>
4490 <classname>Tag</classname>
4491 </entry>
4492 <entry>
4493 <classname>rb_tree_tag</classname>
4494 </entry>
4495 <entry namest="c4" nameend="c7"></entry>
4496 </row>
4497
4498 <row>
4499 <entry>
4500 <classname>Node_Update</classname>
4501 </entry>
4502 <entry>
4503 <classname>null_node_update</classname>
4504 </entry>
4505 <entry namest="c4" nameend="c7"></entry>
4506 </row>
4507
4508 <row>
4509 <entry morerows="2" valign="top">
4510 <classname>Mapped</classname>
4511 </entry>
4512 <entry morerows="2" valign="top">
4513 <classname>cc_hash_table</classname>
4514 </entry>
4515 <entry>
4516 <classname>Comb_Hash_Fn</classname>
4517 </entry>
4518 <entry>
4519 <classname>direct_mask_range_hashing</classname>
4520 </entry>
4521 <entry namest="c6" nameend="c7"></entry>
4522 </row>
4523
4524 <row>
4525 <entry morerows="1" valign="top">
4526 <classname>Resize_Policy</classname>
4527 </entry>
4528 <entry morerows="1" valign="top">
4529 <classname>hash_standard_resize_policy</classname>
4530 </entry>
4531 <entry>
4532 <classname>Size_Policy</classname>
4533 </entry>
4534 <entry>
4535 <classname>hash_exponential_size_policy</classname>
4536 </entry>
4537 </row>
4538
4539 <row>
4540 <entry valign="top">
4541 <classname>Trigger_Policy</classname>
4542 </entry>
4543 <entry>
4544 <classname>hash_load_check_resize_trigger</classname> with
4545 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
4546 </entry>
4547 </row>
4548
4549 </tbody>
4550 </tgroup>
4551 </informaltable>
4552
4553
4554 <para>The graphic below show the results for "multimaps" which
4555 use a hash-based container for primary keys.
4556 </para>
4557
4558 <!-- results graphic -->
4559 <informalfigure>
4560 <mediaobject>
4561 <imageobject>
4562 <imagedata align="center" format="PNG" scale="100"
4563 fileref="../images/pbds_multimap_text_find_timing_test_large_s2p_hash_local.png"/>
4564 </imageobject>
4565 <imageobject>
4566 <imagedata align="center" format="PDF" scale="33"
4567 fileref="../images/pbds_multimap_text_find_timing_test_large_s2p_hash_local.pdf"/>
4568 </imageobject>
4569 </mediaobject>
4570 </informalfigure>
4571
4572 <para>
4573 The abbreviated names in the legend of the graphic above are
4574 instantiated with the types in the following table.
4575 </para>
4576
4577 <informaltable frame="all">
4578
4579 <tgroup cols="7" align="left" colsep="1" rowsep="1">
4580 <colspec colname="c1"/>
4581 <colspec colname="c2"/>
4582 <colspec colname="c3"/>
4583 <colspec colname="c4"/>
4584 <colspec colname="c5"/>
4585 <colspec colname="c6"/>
4586 <colspec colname="c7"/>
4587 <thead>
4588 <row>
4589 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
4590 <entry><emphasis>Parameter</emphasis></entry>
4591 <entry><emphasis>Details</emphasis></entry>
4592 <entry><emphasis>Parameter</emphasis></entry>
4593 <entry><emphasis>Details</emphasis></entry>
4594 <entry><emphasis>Parameter</emphasis></entry>
4595 <entry><emphasis>Details</emphasis></entry>
4596 </row>
4597 </thead>
4598
4599 <tbody>
4600
4601 <!-- native -->
4602 <row>
4603 <?dbhtml bgcolor="#B0B0B0" ?>
4604 <entry namest="c1" nameend="c7">
4605 n_hash_mmap
4606 </entry>
4607 </row>
4608
4609 <row>
4610 <entry>
4611 <classname>std::tr1::unordered_multimap</classname>
4612 </entry>
4613 <entry namest="c2" nameend="c7"></entry>
4614 </row>
4615
4616 <!-- multimap 01 -->
4617 <row>
4618 <?dbhtml bgcolor="#B0B0B0" ?>
4619 <entry namest="c1" nameend="c7">
4620 rb_tree_mmap_lu_mtf_set
4621 </entry>
4622 </row>
4623
4624 <row>
4625 <entry morerows="3" valign="top">
4626 <classname>
4627 cc_hash_table
4628 </classname>
4629 </entry>
4630 <entry>
4631 <classname>Comb_Hash_Fn</classname>
4632 </entry>
4633 <entry>
4634 <classname>direct_mask_range_hashing</classname>
4635 </entry>
4636 <entry namest="c4" nameend="c7"></entry>
4637 </row>
4638 <row>
4639 <entry morerows="1" valign="top">
4640 <classname>Resize_Policy</classname>
4641 </entry>
4642 <entry morerows="1" valign="top">
4643 <classname>hash_standard_resize_policy</classname>
4644 </entry>
4645 <entry>
4646 <classname>Size_Policy</classname>
4647 </entry>
4648 <entry>
4649 <classname>hash_exponential_size_policy</classname>
4650 </entry>
4651 <entry namest="c6" nameend="c7"></entry>
4652 </row>
4653
4654 <row>
4655 <entry valign="top">
4656 <classname>Trigger_Policy</classname>
4657 </entry>
4658 <entry>
4659 <classname>hash_load_check_resize_trigger</classname> with
4660 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
4661 </entry>
4662 <entry namest="c6" nameend="c7"></entry>
4663 </row>
4664
4665 <row>
4666 <entry>
4667 <classname>Mapped</classname>
4668 </entry>
4669 <entry>
4670 <classname>list_update</classname>
4671 </entry>
4672 <entry>
4673 <classname>Update_Policy</classname>
4674 </entry>
4675 <entry>
4676 <classname>lu_move_to_front_policy</classname>
4677 </entry>
4678 <entry namest="c6" nameend="c7"></entry>
4679 </row>
4680
4681 <!-- multimap 02 -->
4682 <row>
4683 <?dbhtml bgcolor="#B0B0B0" ?>
4684 <entry namest="c1" nameend="c7">
4685 rb_tree_mmap_cc_hash_mask_exp_nea_lc_1div8_1div2_nsth_set
4686 </entry>
4687 </row>
4688
4689 <row>
4690 <entry morerows="5" valign="top">
4691 <classname>
4692 cc_hash_table
4693 </classname>
4694 </entry>
4695 <entry>
4696 <classname>Comb_Hash_Fn</classname>
4697 </entry>
4698 <entry>
4699 <classname>direct_mask_range_hashing</classname>
4700 </entry>
4701 <entry namest="c4" nameend="c7"></entry>
4702 </row>
4703 <row>
4704 <entry morerows="1" valign="top">
4705 <classname>Resize_Policy</classname>
4706 </entry>
4707 <entry morerows="1" valign="top">
4708 <classname>hash_standard_resize_policy</classname>
4709 </entry>
4710 <entry>
4711 <classname>Size_Policy</classname>
4712 </entry>
4713 <entry>
4714 <classname>hash_exponential_size_policy</classname>
4715 </entry>
4716 <entry namest="c6" nameend="c7"></entry>
4717 </row>
4718
4719 <row>
4720 <entry valign="top">
4721 <classname>Trigger_Policy</classname>
4722 </entry>
4723 <entry>
4724 <classname>hash_load_check_resize_trigger</classname> with
4725 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
4726 </entry>
4727 <entry namest="c6" nameend="c7"></entry>
4728 </row>
4729
4730 <row>
4731 <entry morerows="2" valign="top">
4732 <classname>Mapped</classname>
4733 </entry>
4734 <entry morerows="2" valign="top">
4735 <classname>cc_hash_table</classname>
4736 </entry>
4737 <entry>
4738 <classname>Comb_Hash_Fn</classname>
4739 </entry>
4740 <entry>
4741 <classname>direct_mask_range_hashing</classname>
4742 </entry>
4743 <entry namest="c6" nameend="c7"></entry>
4744 </row>
4745
4746 <row>
4747 <entry morerows="1" valign="top">
4748 <classname>Resize_Policy</classname>
4749 </entry>
4750 <entry morerows="1" valign="top">
4751 <classname>hash_standard_resize_policy</classname>
4752 </entry>
4753 <entry>
4754 <classname>Size_Policy</classname>
4755 </entry>
4756 <entry>
4757 <classname>hash_exponential_size_policy</classname>
4758 </entry>
4759 </row>
4760
4761 <row>
4762 <entry valign="top">
4763 <classname>Trigger_Policy</classname>
4764 </entry>
4765 <entry>
4766 <classname>hash_load_check_resize_trigger</classname> with
4767 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
4768 </entry>
4769 </row>
4770
4771 </tbody>
4772 </tgroup>
4773 </informaltable>
4774
4775 </section>
4776
4777 <section xml:id="multimap.text_find_large.observations">
4778 <info><title>
4779 Observations
4780 </title></info>
4781
4782 <para>See Observations::Mapping-Semantics
4783 Considerations.</para>
4784
4785 </section>
4786
4787 </section>
4788
4789
4790 <!-- 03 <a href="multimap_text_insert_timing_test_small"> -->
4791 <section xml:id="performance.multimap.text_insert_small">
4792 <info><title>
4793 Text <function>insert</function> with Small
4794 Secondary-to-Primary Key Ratios
4795 </title></info>
4796 <para></para>
4797
4798 <section xml:id="multimap.text_insert_small.info">
4799 <info><title>
4800 Description
4801 </title></info>
4802
4803 <para>This test inserts a number of pairs into a container. The
4804 first item of each pair is a string from an arbitrary text
4805 [wickland96thirty], and
4806 the second is a uniform integer. The container is a
4807 "multimap" - it considers the first member of each pair as a
4808 primary key, and the second member of each pair as a secondary
4809 key. There
4810 are 400 distinct primary keys, and the ratio of secondary keys
4811 to primary keys ranges from 1 to 5.</para>
4812 <para>The test measures the average insert-time as a function of
4813 the number of values inserted. For this library's containers,
4814 it inserts a primary key into the primary associative
4815 container, then a secondary key into the secondary associative
4816 container. For the native multimaps, it obtains a range using
4817 <classname>std::equal_range</classname>, and inserts a value only if it was
4818 not contained already.</para>
4819
4820 <para>
4821 It uses the test file:
4822 <filename>
4823 performance/ext/pb_ds/multimap_text_insert_timing_small.cc
4824 </filename>
4825 </para>
4826
4827 <para>The test checks the insert-time scalability of different
4828 "multimap" designs.</para>
4829
4830 </section>
4831
4832 <section xml:id="multimap.text_insert_small.results">
4833 <info><title>
4834 Results
4835 </title></info>
4836
4837 <para>The graphic below show the results for "multimaps" which
4838 use a tree-based container for primary keys.
4839 </para>
4840
4841 <!-- results graphic -->
4842 <informalfigure>
4843 <mediaobject>
4844 <imageobject>
4845 <imagedata align="center" format="PNG" scale="100"
4846 fileref="../images/pbds_multimap_text_insert_timing_test_small_s2p_tree_local.png"/>
4847 </imageobject>
4848 <imageobject>
4849 <imagedata align="center" format="PDF" scale="33"
4850 fileref="../images/pbds_multimap_text_insert_timing_test_small_s2p_tree_local.pdf"/>
4851 </imageobject>
4852 </mediaobject>
4853 </informalfigure>
4854
4855 <para>
4856 The abbreviated names in the legend of the graphic above are
4857 instantiated with the types in the following table.
4858 </para>
4859
4860
4861 <informaltable frame="all">
4862
4863 <tgroup cols="7" align="left" colsep="1" rowsep="1">
4864 <colspec colname="c1"/>
4865 <colspec colname="c2"/>
4866 <colspec colname="c3"/>
4867 <colspec colname="c4"/>
4868 <colspec colname="c5"/>
4869 <colspec colname="c6"/>
4870 <colspec colname="c7"/>
4871 <thead>
4872 <row>
4873 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
4874 <entry><emphasis>Parameter</emphasis></entry>
4875 <entry><emphasis>Details</emphasis></entry>
4876 <entry><emphasis>Parameter</emphasis></entry>
4877 <entry><emphasis>Details</emphasis></entry>
4878 <entry><emphasis>Parameter</emphasis></entry>
4879 <entry><emphasis>Details</emphasis></entry>
4880 </row>
4881 </thead>
4882
4883 <tbody>
4884
4885 <!-- native -->
4886 <row>
4887 <?dbhtml bgcolor="#B0B0B0" ?>
4888 <entry namest="c1" nameend="c7">
4889 n_mmap
4890 </entry>
4891 </row>
4892
4893 <row>
4894 <entry>
4895 <classname>std::multimap</classname>
4896 </entry>
4897 <entry namest="c2" nameend="c7"></entry>
4898 </row>
4899
4900 <!-- multimap 01 -->
4901 <row>
4902 <?dbhtml bgcolor="#B0B0B0" ?>
4903 <entry namest="c1" nameend="c7">
4904 rb_tree_mmap_lu_mtf_set
4905 </entry>
4906 </row>
4907
4908 <row>
4909 <entry morerows="2" valign="top">
4910 <classname>tree</classname>
4911 </entry>
4912 <entry>
4913 <classname>Tag</classname>
4914 </entry>
4915 <entry>
4916 <classname>rb_tree_tag</classname>
4917 </entry>
4918 <entry namest="c4" nameend="c7"></entry>
4919 </row>
4920
4921 <row>
4922 <entry>
4923 <classname>Node_Update</classname>
4924 </entry>
4925 <entry>
4926 <classname>null_node_update</classname>
4927 </entry>
4928 <entry namest="c4" nameend="c7"></entry>
4929 </row>
4930 <row>
4931 <entry>
4932 <classname>Mapped</classname>
4933 </entry>
4934 <entry>
4935 <classname>list_update</classname>
4936 </entry>
4937 <entry>
4938 <classname>Update_Policy</classname>
4939 </entry>
4940 <entry>
4941 <classname>lu_move_to_front_policy</classname>
4942 </entry>
4943 <entry namest="c6" nameend="c7"></entry>
4944 </row>
4945
4946 <!-- multimap 02 -->
4947 <row>
4948 <?dbhtml bgcolor="#B0B0B0" ?>
4949 <entry namest="c1" nameend="c7">
4950 rb_tree_mmap_cc_hash_mask_exp_nea_lc_1div8_1div2_nsth_set
4951 </entry>
4952 </row>
4953
4954 <row>
4955 <entry morerows="4" valign="top">
4956 <classname>tree</classname>
4957 </entry>
4958 <entry>
4959 <classname>Tag</classname>
4960 </entry>
4961 <entry>
4962 <classname>rb_tree_tag</classname>
4963 </entry>
4964 <entry namest="c4" nameend="c7"></entry>
4965 </row>
4966
4967 <row>
4968 <entry>
4969 <classname>Node_Update</classname>
4970 </entry>
4971 <entry>
4972 <classname>null_node_update</classname>
4973 </entry>
4974 <entry namest="c4" nameend="c7"></entry>
4975 </row>
4976
4977 <row>
4978 <entry morerows="2" valign="top">
4979 <classname>Mapped</classname>
4980 </entry>
4981 <entry morerows="2" valign="top">
4982 <classname>cc_hash_table</classname>
4983 </entry>
4984 <entry>
4985 <classname>Comb_Hash_Fn</classname>
4986 </entry>
4987 <entry>
4988 <classname>direct_mask_range_hashing</classname>
4989 </entry>
4990 <entry namest="c6" nameend="c7"></entry>
4991 </row>
4992
4993 <row>
4994 <entry morerows="1" valign="top">
4995 <classname>Resize_Policy</classname>
4996 </entry>
4997 <entry morerows="1" valign="top">
4998 <classname>hash_standard_resize_policy</classname>
4999 </entry>
5000 <entry>
5001 <classname>Size_Policy</classname>
5002 </entry>
5003 <entry>
5004 <classname>hash_exponential_size_policy</classname>
5005 </entry>
5006 </row>
5007
5008 <row>
5009 <entry valign="top">
5010 <classname>Trigger_Policy</classname>
5011 </entry>
5012 <entry>
5013 <classname>hash_load_check_resize_trigger</classname> with
5014 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
5015 </entry>
5016 </row>
5017
5018 </tbody>
5019 </tgroup>
5020 </informaltable>
5021
5022
5023 <para>The graphic below show the results for "multimaps" which
5024 use a hash-based container for primary keys.
5025 </para>
5026
5027 <!-- results graphic -->
5028 <informalfigure>
5029 <mediaobject>
5030 <imageobject>
5031 <imagedata align="center" format="PNG" scale="100"
5032 fileref="../images/pbds_multimap_text_find_timing_test_small_s2p_hash_local.png"/>
5033 </imageobject>
5034 <imageobject>
5035 <imagedata align="center" format="PDF" scale="33"
5036 fileref="../images/pbds_multimap_text_find_timing_test_small_s2p_hash_local.pdf"/>
5037 </imageobject>
5038 </mediaobject>
5039 </informalfigure>
5040
5041 <para>
5042 The abbreviated names in the legend of the graphic above are
5043 instantiated with the types in the following table.
5044 </para>
5045
5046 <informaltable frame="all">
5047
5048 <tgroup cols="7" align="left" colsep="1" rowsep="1">
5049 <colspec colname="c1"/>
5050 <colspec colname="c2"/>
5051 <colspec colname="c3"/>
5052 <colspec colname="c4"/>
5053 <colspec colname="c5"/>
5054 <colspec colname="c6"/>
5055 <colspec colname="c7"/>
5056 <thead>
5057 <row>
5058 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
5059 <entry><emphasis>Parameter</emphasis></entry>
5060 <entry><emphasis>Details</emphasis></entry>
5061 <entry><emphasis>Parameter</emphasis></entry>
5062 <entry><emphasis>Details</emphasis></entry>
5063 <entry><emphasis>Parameter</emphasis></entry>
5064 <entry><emphasis>Details</emphasis></entry>
5065 </row>
5066 </thead>
5067
5068 <tbody>
5069
5070 <!-- native -->
5071 <row>
5072 <?dbhtml bgcolor="#B0B0B0" ?>
5073 <entry namest="c1" nameend="c7">
5074 n_hash_mmap
5075 </entry>
5076 </row>
5077
5078 <row>
5079 <entry>
5080 <classname>std::tr1::unordered_multimap</classname>
5081 </entry>
5082 <entry namest="c2" nameend="c7"></entry>
5083 </row>
5084
5085 <!-- multimap 01 -->
5086 <row>
5087 <?dbhtml bgcolor="#B0B0B0" ?>
5088 <entry namest="c1" nameend="c7">
5089 rb_tree_mmap_lu_mtf_set
5090 </entry>
5091 </row>
5092
5093 <row>
5094 <entry morerows="3" valign="top">
5095 <classname>
5096 cc_hash_table
5097 </classname>
5098 </entry>
5099 <entry>
5100 <classname>Comb_Hash_Fn</classname>
5101 </entry>
5102 <entry>
5103 <classname>direct_mask_range_hashing</classname>
5104 </entry>
5105 <entry namest="c4" nameend="c7"></entry>
5106 </row>
5107 <row>
5108 <entry morerows="1" valign="top">
5109 <classname>Resize_Policy</classname>
5110 </entry>
5111 <entry morerows="1" valign="top">
5112 <classname>hash_standard_resize_policy</classname>
5113 </entry>
5114 <entry>
5115 <classname>Size_Policy</classname>
5116 </entry>
5117 <entry>
5118 <classname>hash_exponential_size_policy</classname>
5119 </entry>
5120 <entry namest="c6" nameend="c7"></entry>
5121 </row>
5122
5123 <row>
5124 <entry valign="top">
5125 <classname>Trigger_Policy</classname>
5126 </entry>
5127 <entry>
5128 <classname>hash_load_check_resize_trigger</classname> with
5129 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
5130 </entry>
5131 <entry namest="c6" nameend="c7"></entry>
5132 </row>
5133
5134 <row>
5135 <entry>
5136 <classname>Mapped</classname>
5137 </entry>
5138 <entry>
5139 <classname>list_update</classname>
5140 </entry>
5141 <entry>
5142 <classname>Update_Policy</classname>
5143 </entry>
5144 <entry>
5145 <classname>lu_move_to_front_policy</classname>
5146 </entry>
5147 <entry namest="c6" nameend="c7"></entry>
5148 </row>
5149
5150 <!-- multimap 02 -->
5151 <row>
5152 <?dbhtml bgcolor="#B0B0B0" ?>
5153 <entry namest="c1" nameend="c7">
5154 rb_tree_mmap_cc_hash_mask_exp_nea_lc_1div8_1div2_nsth_set
5155 </entry>
5156 </row>
5157
5158 <row>
5159 <entry morerows="5" valign="top">
5160 <classname>
5161 cc_hash_table
5162 </classname>
5163 </entry>
5164 <entry>
5165 <classname>Comb_Hash_Fn</classname>
5166 </entry>
5167 <entry>
5168 <classname>direct_mask_range_hashing</classname>
5169 </entry>
5170 <entry namest="c4" nameend="c7"></entry>
5171 </row>
5172 <row>
5173 <entry morerows="1" valign="top">
5174 <classname>Resize_Policy</classname>
5175 </entry>
5176 <entry morerows="1" valign="top">
5177 <classname>hash_standard_resize_policy</classname>
5178 </entry>
5179 <entry>
5180 <classname>Size_Policy</classname>
5181 </entry>
5182 <entry>
5183 <classname>hash_exponential_size_policy</classname>
5184 </entry>
5185 <entry namest="c6" nameend="c7"></entry>
5186 </row>
5187
5188 <row>
5189 <entry valign="top">
5190 <classname>Trigger_Policy</classname>
5191 </entry>
5192 <entry>
5193 <classname>hash_load_check_resize_trigger</classname> with
5194 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
5195 </entry>
5196 <entry namest="c6" nameend="c7"></entry>
5197 </row>
5198
5199 <row>
5200 <entry morerows="2" valign="top">
5201 <classname>Mapped</classname>
5202 </entry>
5203 <entry morerows="2" valign="top">
5204 <classname>cc_hash_table</classname>
5205 </entry>
5206 <entry>
5207 <classname>Comb_Hash_Fn</classname>
5208 </entry>
5209 <entry>
5210 <classname>direct_mask_range_hashing</classname>
5211 </entry>
5212 <entry namest="c6" nameend="c7"></entry>
5213 </row>
5214
5215 <row>
5216 <entry morerows="1" valign="top">
5217 <classname>Resize_Policy</classname>
5218 </entry>
5219 <entry morerows="1" valign="top">
5220 <classname>hash_standard_resize_policy</classname>
5221 </entry>
5222 <entry>
5223 <classname>Size_Policy</classname>
5224 </entry>
5225 <entry>
5226 <classname>hash_exponential_size_policy</classname>
5227 </entry>
5228 </row>
5229
5230 <row>
5231 <entry valign="top">
5232 <classname>Trigger_Policy</classname>
5233 </entry>
5234 <entry>
5235 <classname>hash_load_check_resize_trigger</classname> with
5236 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
5237 </entry>
5238 </row>
5239
5240 </tbody>
5241 </tgroup>
5242 </informaltable>
5243
5244 </section>
5245
5246 <section xml:id="multimap.text_insert_small.observations">
5247 <info><title>
5248 Observations
5249 </title></info>
5250
5251 <para>See Observations::Mapping-Semantics
5252 Considerations.</para>
5253
5254 </section>
5255
5256 </section>
5257
5258
5259 <!-- 04 <a href="multimap_text_insert_timing_test_large"> -->
5260 <section xml:id="performance.multimap.text_insert_large">
5261 <info><title>
5262 Text <function>insert</function> with Small
5263 Secondary-to-Primary Key Ratios
5264 </title></info>
5265 <para></para>
5266
5267 <section xml:id="multimap.text_insert_large.info">
5268 <info><title>
5269 Description
5270 </title></info>
5271
5272 <para>This test inserts a number of pairs into a container. The
5273 first item of each pair is a string from an arbitrary text
5274 [wickland96thirty], and
5275 the second is a uniform integer. The container is a
5276 "multimap" - it considers the first member of each pair as a
5277 primary key, and the second member of each pair as a secondary
5278 key. There
5279 are 400 distinct primary keys, and the ratio of secondary keys
5280 to primary keys ranges from 1 to 5.</para>
5281 <para>The test measures the average insert-time as a function of
5282 the number of values inserted. For this library's containers,
5283 it inserts a primary key into the primary associative
5284 container, then a secondary key into the secondary associative
5285 container. For the native multimaps, it obtains a range using
5286 <classname>std::equal_range</classname>, and inserts a value only if it was
5287 not contained already.</para>
5288
5289 <para>
5290 It uses the test file:
5291 <filename>
5292 performance/ext/pb_ds/multimap_text_insert_timing_large.cc
5293 </filename>
5294 </para>
5295
5296 <para>The test checks the insert-time scalability of different
5297 "multimap" designs.</para>
5298
5299 </section>
5300
5301 <section xml:id="multimap.text_insert_large.results">
5302 <info><title>
5303 Results
5304 </title></info>
5305
5306 <para>The graphic below show the results for "multimaps" which
5307 use a tree-based container for primary keys.
5308 </para>
5309
5310 <!-- results graphic -->
5311 <informalfigure>
5312 <mediaobject>
5313 <imageobject>
5314 <imagedata align="center" format="PNG" scale="100"
5315 fileref="../images/pbds_multimap_text_insert_timing_test_large_s2p_tree_local.png"/>
5316 </imageobject>
5317 <imageobject>
5318 <imagedata align="center" format="PDF" scale="33"
5319 fileref="../images/pbds_multimap_text_insert_timing_test_large_s2p_tree_local.pdf"/>
5320 </imageobject>
5321 </mediaobject>
5322 </informalfigure>
5323
5324 <para>
5325 The abbreviated names in the legend of the graphic above are
5326 instantiated with the types in the following table.
5327 </para>
5328
5329
5330 <informaltable frame="all">
5331
5332 <tgroup cols="7" align="left" colsep="1" rowsep="1">
5333 <colspec colname="c1"/>
5334 <colspec colname="c2"/>
5335 <colspec colname="c3"/>
5336 <colspec colname="c4"/>
5337 <colspec colname="c5"/>
5338 <colspec colname="c6"/>
5339 <colspec colname="c7"/>
5340 <thead>
5341 <row>
5342 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
5343 <entry><emphasis>Parameter</emphasis></entry>
5344 <entry><emphasis>Details</emphasis></entry>
5345 <entry><emphasis>Parameter</emphasis></entry>
5346 <entry><emphasis>Details</emphasis></entry>
5347 <entry><emphasis>Parameter</emphasis></entry>
5348 <entry><emphasis>Details</emphasis></entry>
5349 </row>
5350 </thead>
5351
5352 <tbody>
5353
5354 <!-- native -->
5355 <row>
5356 <?dbhtml bgcolor="#B0B0B0" ?>
5357 <entry namest="c1" nameend="c7">
5358 n_mmap
5359 </entry>
5360 </row>
5361
5362 <row>
5363 <entry>
5364 <classname>std::multimap</classname>
5365 </entry>
5366 <entry namest="c2" nameend="c7"></entry>
5367 </row>
5368
5369 <!-- multimap 01 -->
5370 <row>
5371 <?dbhtml bgcolor="#B0B0B0" ?>
5372 <entry namest="c1" nameend="c7">
5373 rb_tree_mmap_lu_mtf_set
5374 </entry>
5375 </row>
5376
5377 <row>
5378 <entry morerows="2" valign="top">
5379 <classname>tree</classname>
5380 </entry>
5381 <entry>
5382 <classname>Tag</classname>
5383 </entry>
5384 <entry>
5385 <classname>rb_tree_tag</classname>
5386 </entry>
5387 <entry namest="c4" nameend="c7"></entry>
5388 </row>
5389
5390 <row>
5391 <entry>
5392 <classname>Node_Update</classname>
5393 </entry>
5394 <entry>
5395 <classname>null_node_update</classname>
5396 </entry>
5397 <entry namest="c4" nameend="c7"></entry>
5398 </row>
5399 <row>
5400 <entry>
5401 <classname>Mapped</classname>
5402 </entry>
5403 <entry>
5404 <classname>list_update</classname>
5405 </entry>
5406 <entry>
5407 <classname>Update_Policy</classname>
5408 </entry>
5409 <entry>
5410 <classname>lu_move_to_front_policy</classname>
5411 </entry>
5412 <entry namest="c6" nameend="c7"></entry>
5413 </row>
5414
5415 <!-- multimap 02 -->
5416 <row>
5417 <?dbhtml bgcolor="#B0B0B0" ?>
5418 <entry namest="c1" nameend="c7">
5419 rb_tree_mmap_cc_hash_mask_exp_nea_lc_1div8_1div2_nsth_set
5420 </entry>
5421 </row>
5422
5423 <row>
5424 <entry morerows="4" valign="top">
5425 <classname>tree</classname>
5426 </entry>
5427 <entry>
5428 <classname>Tag</classname>
5429 </entry>
5430 <entry>
5431 <classname>rb_tree_tag</classname>
5432 </entry>
5433 <entry namest="c4" nameend="c7"></entry>
5434 </row>
5435
5436 <row>
5437 <entry>
5438 <classname>Node_Update</classname>
5439 </entry>
5440 <entry>
5441 <classname>null_node_update</classname>
5442 </entry>
5443 <entry namest="c4" nameend="c7"></entry>
5444 </row>
5445
5446 <row>
5447 <entry morerows="2" valign="top">
5448 <classname>Mapped</classname>
5449 </entry>
5450 <entry morerows="2" valign="top">
5451 <classname>cc_hash_table</classname>
5452 </entry>
5453 <entry>
5454 <classname>Comb_Hash_Fn</classname>
5455 </entry>
5456 <entry>
5457 <classname>direct_mask_range_hashing</classname>
5458 </entry>
5459 <entry namest="c6" nameend="c7"></entry>
5460 </row>
5461
5462 <row>
5463 <entry morerows="1" valign="top">
5464 <classname>Resize_Policy</classname>
5465 </entry>
5466 <entry morerows="1" valign="top">
5467 <classname>hash_standard_resize_policy</classname>
5468 </entry>
5469 <entry>
5470 <classname>Size_Policy</classname>
5471 </entry>
5472 <entry>
5473 <classname>hash_exponential_size_policy</classname>
5474 </entry>
5475 </row>
5476
5477 <row>
5478 <entry valign="top">
5479 <classname>Trigger_Policy</classname>
5480 </entry>
5481 <entry>
5482 <classname>hash_load_check_resize_trigger</classname> with
5483 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
5484 </entry>
5485 </row>
5486
5487 </tbody>
5488 </tgroup>
5489 </informaltable>
5490
5491
5492 <para>The graphic below show the results for "multimaps" which
5493 use a hash-based container for primary keys.
5494 </para>
5495
5496 <!-- results graphic -->
5497 <informalfigure>
5498 <mediaobject>
5499 <imageobject>
5500 <imagedata align="center" format="PNG" scale="100"
5501 fileref="../images/pbds_multimap_text_find_timing_test_large_s2p_hash_local.png"/>
5502 </imageobject>
5503 <imageobject>
5504 <imagedata align="center" format="PDF" scale="33"
5505 fileref="../images/pbds_multimap_text_find_timing_test_large_s2p_hash_local.pdf"/>
5506 </imageobject>
5507 </mediaobject>
5508 </informalfigure>
5509
5510 <para>
5511 The abbreviated names in the legend of the graphic above are
5512 instantiated with the types in the following table.
5513 </para>
5514
5515 <informaltable frame="all">
5516
5517 <tgroup cols="7" align="left" colsep="1" rowsep="1">
5518 <colspec colname="c1"/>
5519 <colspec colname="c2"/>
5520 <colspec colname="c3"/>
5521 <colspec colname="c4"/>
5522 <colspec colname="c5"/>
5523 <colspec colname="c6"/>
5524 <colspec colname="c7"/>
5525 <thead>
5526 <row>
5527 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
5528 <entry><emphasis>Parameter</emphasis></entry>
5529 <entry><emphasis>Details</emphasis></entry>
5530 <entry><emphasis>Parameter</emphasis></entry>
5531 <entry><emphasis>Details</emphasis></entry>
5532 <entry><emphasis>Parameter</emphasis></entry>
5533 <entry><emphasis>Details</emphasis></entry>
5534 </row>
5535 </thead>
5536
5537 <tbody>
5538
5539 <!-- native -->
5540 <row>
5541 <?dbhtml bgcolor="#B0B0B0" ?>
5542 <entry namest="c1" nameend="c7">
5543 n_hash_mmap
5544 </entry>
5545 </row>
5546
5547 <row>
5548 <entry>
5549 <classname>std::tr1::unordered_multimap</classname>
5550 </entry>
5551 <entry namest="c2" nameend="c7"></entry>
5552 </row>
5553
5554 <!-- multimap 01 -->
5555 <row>
5556 <?dbhtml bgcolor="#B0B0B0" ?>
5557 <entry namest="c1" nameend="c7">
5558 rb_tree_mmap_lu_mtf_set
5559 </entry>
5560 </row>
5561
5562 <row>
5563 <entry morerows="3" valign="top">
5564 <classname>
5565 cc_hash_table
5566 </classname>
5567 </entry>
5568 <entry>
5569 <classname>Comb_Hash_Fn</classname>
5570 </entry>
5571 <entry>
5572 <classname>direct_mask_range_hashing</classname>
5573 </entry>
5574 <entry namest="c4" nameend="c7"></entry>
5575 </row>
5576 <row>
5577 <entry morerows="1" valign="top">
5578 <classname>Resize_Policy</classname>
5579 </entry>
5580 <entry morerows="1" valign="top">
5581 <classname>hash_standard_resize_policy</classname>
5582 </entry>
5583 <entry>
5584 <classname>Size_Policy</classname>
5585 </entry>
5586 <entry>
5587 <classname>hash_exponential_size_policy</classname>
5588 </entry>
5589 <entry namest="c6" nameend="c7"></entry>
5590 </row>
5591
5592 <row>
5593 <entry valign="top">
5594 <classname>Trigger_Policy</classname>
5595 </entry>
5596 <entry>
5597 <classname>hash_load_check_resize_trigger</classname> with
5598 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
5599 </entry>
5600 <entry namest="c6" nameend="c7"></entry>
5601 </row>
5602
5603 <row>
5604 <entry>
5605 <classname>Mapped</classname>
5606 </entry>
5607 <entry>
5608 <classname>list_update</classname>
5609 </entry>
5610 <entry>
5611 <classname>Update_Policy</classname>
5612 </entry>
5613 <entry>
5614 <classname>lu_move_to_front_policy</classname>
5615 </entry>
5616 <entry namest="c6" nameend="c7"></entry>
5617 </row>
5618
5619 <!-- multimap 02 -->
5620 <row>
5621 <?dbhtml bgcolor="#B0B0B0" ?>
5622 <entry namest="c1" nameend="c7">
5623 rb_tree_mmap_cc_hash_mask_exp_nea_lc_1div8_1div2_nsth_set
5624 </entry>
5625 </row>
5626
5627 <row>
5628 <entry morerows="5" valign="top">
5629 <classname>
5630 cc_hash_table
5631 </classname>
5632 </entry>
5633 <entry>
5634 <classname>Comb_Hash_Fn</classname>
5635 </entry>
5636 <entry>
5637 <classname>direct_mask_range_hashing</classname>
5638 </entry>
5639 <entry namest="c4" nameend="c7"></entry>
5640 </row>
5641 <row>
5642 <entry morerows="1" valign="top">
5643 <classname>Resize_Policy</classname>
5644 </entry>
5645 <entry morerows="1" valign="top">
5646 <classname>hash_standard_resize_policy</classname>
5647 </entry>
5648 <entry>
5649 <classname>Size_Policy</classname>
5650 </entry>
5651 <entry>
5652 <classname>hash_exponential_size_policy</classname>
5653 </entry>
5654 <entry namest="c6" nameend="c7"></entry>
5655 </row>
5656
5657 <row>
5658 <entry valign="top">
5659 <classname>Trigger_Policy</classname>
5660 </entry>
5661 <entry>
5662 <classname>hash_load_check_resize_trigger</classname> with
5663 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
5664 </entry>
5665 <entry namest="c6" nameend="c7"></entry>
5666 </row>
5667
5668 <row>
5669 <entry morerows="2" valign="top">
5670 <classname>Mapped</classname>
5671 </entry>
5672 <entry morerows="2" valign="top">
5673 <classname>cc_hash_table</classname>
5674 </entry>
5675 <entry>
5676 <classname>Comb_Hash_Fn</classname>
5677 </entry>
5678 <entry>
5679 <classname>direct_mask_range_hashing</classname>
5680 </entry>
5681 <entry namest="c6" nameend="c7"></entry>
5682 </row>
5683
5684 <row>
5685 <entry morerows="1" valign="top">
5686 <classname>Resize_Policy</classname>
5687 </entry>
5688 <entry morerows="1" valign="top">
5689 <classname>hash_standard_resize_policy</classname>
5690 </entry>
5691 <entry>
5692 <classname>Size_Policy</classname>
5693 </entry>
5694 <entry>
5695 <classname>hash_exponential_size_policy</classname>
5696 </entry>
5697 </row>
5698
5699 <row>
5700 <entry valign="top">
5701 <classname>Trigger_Policy</classname>
5702 </entry>
5703 <entry>
5704 <classname>hash_load_check_resize_trigger</classname> with
5705 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
5706 </entry>
5707 </row>
5708
5709 </tbody>
5710 </tgroup>
5711 </informaltable>
5712
5713 </section>
5714
5715 <section xml:id="multimap.text_insert_large.observations">
5716 <info><title>
5717 Observations
5718 </title></info>
5719
5720 <para>See Observations::Mapping-Semantics
5721 Considerations.</para>
5722
5723 </section>
5724
5725 </section>
5726
5727
5728 <!-- 05 <a href="multimap_text_insert_mem_usage_test_small"> -->
5729 <section xml:id="performance.multimap.text_insert_mem_small">
5730 <info><title>
5731 Text <function>insert</function> with Small
5732 Secondary-to-Primary Key Ratios Memory Use
5733 </title></info>
5734 <para></para>
5735
5736 <section xml:id="multimap.text_insert_mem_small.info">
5737 <info><title>
5738 Description
5739 </title></info>
5740 <para>This test inserts a number of pairs into a container. The
5741 first item of each pair is a string from an arbitrary text
5742 [wickland96thirty], and
5743 the second is a uniform integer. The container is a
5744 "multimap" - it considers the first member of each pair as a
5745 primary key, and the second member of each pair as a secondary
5746 key. There
5747 are 100 distinct primary keys, and the ratio of secondary keys
5748 to primary keys ranges to about 20.</para>
5749 <para>The test measures the memory use as a function of the number
5750 of values inserted.</para>
5751
5752 <para>
5753 It uses the test file:
5754 <filename>
5755 performance/ext/pb_ds/multimap_text_insert_mem_usage_small.cc
5756 </filename>
5757 </para>
5758
5759 <para>The test checks the memory scalability of different
5760 "multimap" designs.</para>
5761
5762 </section>
5763
5764 <section xml:id="multimap.text_insert_mem_small.results">
5765 <info><title>
5766 Results
5767 </title></info>
5768
5769 <para>The graphic below show the results for "multimaps" which
5770 use a tree-based container for primary keys.
5771 </para>
5772
5773 <!-- results graphic -->
5774 <informalfigure>
5775 <mediaobject>
5776 <imageobject>
5777 <imagedata align="center" format="PNG" scale="100"
5778 fileref="../images/pbds_multimap_text_insert_mem_usage_test_small_s2p_tree_local.png"/>
5779 </imageobject>
5780 <imageobject>
5781 <imagedata align="center" format="PDF" scale="33"
5782 fileref="../images/pbds_multimap_text_insert_mem_usage_test_small_s2p_tree_local.pdf"/>
5783 </imageobject>
5784 </mediaobject>
5785 </informalfigure>
5786
5787 <para>
5788 The abbreviated names in the legend of the graphic above are
5789 instantiated with the types in the following table.
5790 </para>
5791
5792
5793 <informaltable frame="all">
5794
5795 <tgroup cols="7" align="left" colsep="1" rowsep="1">
5796 <colspec colname="c1"/>
5797 <colspec colname="c2"/>
5798 <colspec colname="c3"/>
5799 <colspec colname="c4"/>
5800 <colspec colname="c5"/>
5801 <colspec colname="c6"/>
5802 <colspec colname="c7"/>
5803 <thead>
5804 <row>
5805 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
5806 <entry><emphasis>Parameter</emphasis></entry>
5807 <entry><emphasis>Details</emphasis></entry>
5808 <entry><emphasis>Parameter</emphasis></entry>
5809 <entry><emphasis>Details</emphasis></entry>
5810 <entry><emphasis>Parameter</emphasis></entry>
5811 <entry><emphasis>Details</emphasis></entry>
5812 </row>
5813 </thead>
5814
5815 <tbody>
5816
5817 <!-- native -->
5818 <row>
5819 <?dbhtml bgcolor="#B0B0B0" ?>
5820 <entry namest="c1" nameend="c7">
5821 n_mmap
5822 </entry>
5823 </row>
5824
5825 <row>
5826 <entry>
5827 <classname>std::multimap</classname>
5828 </entry>
5829 <entry namest="c2" nameend="c7"></entry>
5830 </row>
5831
5832 <!-- multimap 01 -->
5833 <row>
5834 <?dbhtml bgcolor="#B0B0B0" ?>
5835 <entry namest="c1" nameend="c7">
5836 rb_tree_mmap_lu_mtf_set
5837 </entry>
5838 </row>
5839
5840 <row>
5841 <entry morerows="2" valign="top">
5842 <classname>tree</classname>
5843 </entry>
5844 <entry>
5845 <classname>Tag</classname>
5846 </entry>
5847 <entry>
5848 <classname>rb_tree_tag</classname>
5849 </entry>
5850 <entry namest="c4" nameend="c7"></entry>
5851 </row>
5852
5853 <row>
5854 <entry>
5855 <classname>Node_Update</classname>
5856 </entry>
5857 <entry>
5858 <classname>null_node_update</classname>
5859 </entry>
5860 <entry namest="c4" nameend="c7"></entry>
5861 </row>
5862 <row>
5863 <entry>
5864 <classname>Mapped</classname>
5865 </entry>
5866 <entry>
5867 <classname>list_update</classname>
5868 </entry>
5869 <entry>
5870 <classname>Update_Policy</classname>
5871 </entry>
5872 <entry>
5873 <classname>lu_move_to_front_policy</classname>
5874 </entry>
5875 <entry namest="c6" nameend="c7"></entry>
5876 </row>
5877
5878 <!-- multimap 02 -->
5879 <row>
5880 <?dbhtml bgcolor="#B0B0B0" ?>
5881 <entry namest="c1" nameend="c7">
5882 rb_tree_mmap_cc_hash_mask_exp_nea_lc_1div8_1div2_nsth_set
5883 </entry>
5884 </row>
5885
5886 <row>
5887 <entry morerows="4" valign="top">
5888 <classname>tree</classname>
5889 </entry>
5890 <entry>
5891 <classname>Tag</classname>
5892 </entry>
5893 <entry>
5894 <classname>rb_tree_tag</classname>
5895 </entry>
5896 <entry namest="c4" nameend="c7"></entry>
5897 </row>
5898
5899 <row>
5900 <entry>
5901 <classname>Node_Update</classname>
5902 </entry>
5903 <entry>
5904 <classname>null_node_update</classname>
5905 </entry>
5906 <entry namest="c4" nameend="c7"></entry>
5907 </row>
5908
5909 <row>
5910 <entry morerows="2" valign="top">
5911 <classname>Mapped</classname>
5912 </entry>
5913 <entry morerows="2" valign="top">
5914 <classname>cc_hash_table</classname>
5915 </entry>
5916 <entry>
5917 <classname>Comb_Hash_Fn</classname>
5918 </entry>
5919 <entry>
5920 <classname>direct_mask_range_hashing</classname>
5921 </entry>
5922 <entry namest="c6" nameend="c7"></entry>
5923 </row>
5924
5925 <row>
5926 <entry morerows="1" valign="top">
5927 <classname>Resize_Policy</classname>
5928 </entry>
5929 <entry morerows="1" valign="top">
5930 <classname>hash_standard_resize_policy</classname>
5931 </entry>
5932 <entry>
5933 <classname>Size_Policy</classname>
5934 </entry>
5935 <entry>
5936 <classname>hash_exponential_size_policy</classname>
5937 </entry>
5938 </row>
5939
5940 <row>
5941 <entry valign="top">
5942 <classname>Trigger_Policy</classname>
5943 </entry>
5944 <entry>
5945 <classname>hash_load_check_resize_trigger</classname> with
5946 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
5947 </entry>
5948 </row>
5949
5950 </tbody>
5951 </tgroup>
5952 </informaltable>
5953
5954
5955 <para>The graphic below show the results for "multimaps" which
5956 use a hash-based container for primary keys.
5957 </para>
5958
5959 <!-- results graphic -->
5960 <informalfigure>
5961 <mediaobject>
5962 <imageobject>
5963 <imagedata align="center" format="PNG" scale="100"
5964 fileref="../images/pbds_multimap_text_find_timing_test_large_s2p_hash_local.png"/>
5965 </imageobject>
5966 <imageobject>
5967 <imagedata align="center" format="PDF" scale="33"
5968 fileref="../images/pbds_multimap_text_find_timing_test_large_s2p_hash_local.pdf"/>
5969 </imageobject>
5970 </mediaobject>
5971 </informalfigure>
5972
5973 <para>
5974 The abbreviated names in the legend of the graphic above are
5975 instantiated with the types in the following table.
5976 </para>
5977
5978 <informaltable frame="all">
5979
5980 <tgroup cols="7" align="left" colsep="1" rowsep="1">
5981 <colspec colname="c1"/>
5982 <colspec colname="c2"/>
5983 <colspec colname="c3"/>
5984 <colspec colname="c4"/>
5985 <colspec colname="c5"/>
5986 <colspec colname="c6"/>
5987 <colspec colname="c7"/>
5988 <thead>
5989 <row>
5990 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
5991 <entry><emphasis>Parameter</emphasis></entry>
5992 <entry><emphasis>Details</emphasis></entry>
5993 <entry><emphasis>Parameter</emphasis></entry>
5994 <entry><emphasis>Details</emphasis></entry>
5995 <entry><emphasis>Parameter</emphasis></entry>
5996 <entry><emphasis>Details</emphasis></entry>
5997 </row>
5998 </thead>
5999
6000 <tbody>
6001
6002 <!-- native -->
6003 <row>
6004 <?dbhtml bgcolor="#B0B0B0" ?>
6005 <entry namest="c1" nameend="c7">
6006 n_hash_mmap
6007 </entry>
6008 </row>
6009
6010 <row>
6011 <entry>
6012 <classname>std::tr1::unordered_multimap</classname>
6013 </entry>
6014 <entry namest="c2" nameend="c7"></entry>
6015 </row>
6016
6017 <!-- multimap 01 -->
6018 <row>
6019 <?dbhtml bgcolor="#B0B0B0" ?>
6020 <entry namest="c1" nameend="c7">
6021 rb_tree_mmap_lu_mtf_set
6022 </entry>
6023 </row>
6024
6025 <row>
6026 <entry morerows="3" valign="top">
6027 <classname>
6028 cc_hash_table
6029 </classname>
6030 </entry>
6031 <entry>
6032 <classname>Comb_Hash_Fn</classname>
6033 </entry>
6034 <entry>
6035 <classname>direct_mask_range_hashing</classname>
6036 </entry>
6037 <entry namest="c4" nameend="c7"></entry>
6038 </row>
6039 <row>
6040 <entry morerows="1" valign="top">
6041 <classname>Resize_Policy</classname>
6042 </entry>
6043 <entry morerows="1" valign="top">
6044 <classname>hash_standard_resize_policy</classname>
6045 </entry>
6046 <entry>
6047 <classname>Size_Policy</classname>
6048 </entry>
6049 <entry>
6050 <classname>hash_exponential_size_policy</classname>
6051 </entry>
6052 <entry namest="c6" nameend="c7"></entry>
6053 </row>
6054
6055 <row>
6056 <entry valign="top">
6057 <classname>Trigger_Policy</classname>
6058 </entry>
6059 <entry>
6060 <classname>hash_load_check_resize_trigger</classname> with
6061 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
6062 </entry>
6063 <entry namest="c6" nameend="c7"></entry>
6064 </row>
6065
6066 <row>
6067 <entry>
6068 <classname>Mapped</classname>
6069 </entry>
6070 <entry>
6071 <classname>list_update</classname>
6072 </entry>
6073 <entry>
6074 <classname>Update_Policy</classname>
6075 </entry>
6076 <entry>
6077 <classname>lu_move_to_front_policy</classname>
6078 </entry>
6079 <entry namest="c6" nameend="c7"></entry>
6080 </row>
6081
6082 <!-- multimap 02 -->
6083 <row>
6084 <?dbhtml bgcolor="#B0B0B0" ?>
6085 <entry namest="c1" nameend="c7">
6086 rb_tree_mmap_cc_hash_mask_exp_nea_lc_1div8_1div2_nsth_set
6087 </entry>
6088 </row>
6089
6090 <row>
6091 <entry morerows="5" valign="top">
6092 <classname>
6093 cc_hash_table
6094 </classname>
6095 </entry>
6096 <entry>
6097 <classname>Comb_Hash_Fn</classname>
6098 </entry>
6099 <entry>
6100 <classname>direct_mask_range_hashing</classname>
6101 </entry>
6102 <entry namest="c4" nameend="c7"></entry>
6103 </row>
6104 <row>
6105 <entry morerows="1" valign="top">
6106 <classname>Resize_Policy</classname>
6107 </entry>
6108 <entry morerows="1" valign="top">
6109 <classname>hash_standard_resize_policy</classname>
6110 </entry>
6111 <entry>
6112 <classname>Size_Policy</classname>
6113 </entry>
6114 <entry>
6115 <classname>hash_exponential_size_policy</classname>
6116 </entry>
6117 <entry namest="c6" nameend="c7"></entry>
6118 </row>
6119
6120 <row>
6121 <entry valign="top">
6122 <classname>Trigger_Policy</classname>
6123 </entry>
6124 <entry>
6125 <classname>hash_load_check_resize_trigger</classname> with
6126 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
6127 </entry>
6128 <entry namest="c6" nameend="c7"></entry>
6129 </row>
6130
6131 <row>
6132 <entry morerows="2" valign="top">
6133 <classname>Mapped</classname>
6134 </entry>
6135 <entry morerows="2" valign="top">
6136 <classname>cc_hash_table</classname>
6137 </entry>
6138 <entry>
6139 <classname>Comb_Hash_Fn</classname>
6140 </entry>
6141 <entry>
6142 <classname>direct_mask_range_hashing</classname>
6143 </entry>
6144 <entry namest="c6" nameend="c7"></entry>
6145 </row>
6146
6147 <row>
6148 <entry morerows="1" valign="top">
6149 <classname>Resize_Policy</classname>
6150 </entry>
6151 <entry morerows="1" valign="top">
6152 <classname>hash_standard_resize_policy</classname>
6153 </entry>
6154 <entry>
6155 <classname>Size_Policy</classname>
6156 </entry>
6157 <entry>
6158 <classname>hash_exponential_size_policy</classname>
6159 </entry>
6160 </row>
6161
6162 <row>
6163 <entry valign="top">
6164 <classname>Trigger_Policy</classname>
6165 </entry>
6166 <entry>
6167 <classname>hash_load_check_resize_trigger</classname> with
6168 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
6169 </entry>
6170 </row>
6171
6172 </tbody>
6173 </tgroup>
6174 </informaltable>
6175
6176 </section>
6177
6178 <section xml:id="multimap.text_insert_mem_small.observations">
6179 <info><title>
6180 Observations
6181 </title></info>
6182
6183 <para>See Observations::Mapping-Semantics
6184 Considerations.</para>
6185
6186 </section>
6187
6188 </section>
6189
6190 <!-- 06 <a href="multimap_text_insert_mem_usage_test_large"> -->
6191 <section xml:id="performance.multimap.text_insert_mem_large">
6192 <info><title>
6193 Text <function>insert</function> with Small
6194 Secondary-to-Primary Key Ratios Memory Use
6195 </title></info>
6196 <para></para>
6197
6198 <section xml:id="multimap.text_insert_mem_large.info">
6199 <info><title>
6200 Description
6201 </title></info>
6202 <para>This test inserts a number of pairs into a container. The
6203 first item of each pair is a string from an arbitrary text
6204 [wickland96thirty], and
6205 the second is a uniform integer. The container is a
6206 "multimap" - it considers the first member of each pair as a
6207 primary key, and the second member of each pair as a secondary
6208 key. There
6209 are 100 distinct primary keys, and the ratio of secondary keys
6210 to primary keys ranges to about 20.</para>
6211 <para>The test measures the memory use as a function of the number
6212 of values inserted.</para>
6213
6214 <para>
6215 It uses the test file:
6216 <filename>
6217 performance/ext/pb_ds/multimap_text_insert_mem_usage_large.cc
6218 </filename>
6219 </para>
6220
6221 <para>The test checks the memory scalability of different
6222 "multimap" designs.</para>
6223
6224 </section>
6225
6226 <section xml:id="multimap.text_insert_mem_large.results">
6227 <info><title>
6228 Results
6229 </title></info>
6230
6231 <para>The graphic below show the results for "multimaps" which
6232 use a tree-based container for primary keys.
6233 </para>
6234
6235 <!-- results graphic -->
6236 <informalfigure>
6237 <mediaobject>
6238 <imageobject>
6239 <imagedata align="center" format="PNG" scale="100"
6240 fileref="../images/pbds_multimap_text_insert_mem_usage_test_large_s2p_tree_local.png"/>
6241 </imageobject>
6242 <imageobject>
6243 <imagedata align="center" format="PDF" scale="33"
6244 fileref="../images/pbds_multimap_text_insert_mem_usage_test_large_s2p_tree_local.pdf"/>
6245 </imageobject>
6246 </mediaobject>
6247 </informalfigure>
6248
6249 <para>
6250 The abbreviated names in the legend of the graphic above are
6251 instantiated with the types in the following table.
6252 </para>
6253
6254
6255 <informaltable frame="all">
6256
6257 <tgroup cols="7" align="left" colsep="1" rowsep="1">
6258 <colspec colname="c1"/>
6259 <colspec colname="c2"/>
6260 <colspec colname="c3"/>
6261 <colspec colname="c4"/>
6262 <colspec colname="c5"/>
6263 <colspec colname="c6"/>
6264 <colspec colname="c7"/>
6265 <thead>
6266 <row>
6267 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
6268 <entry><emphasis>Parameter</emphasis></entry>
6269 <entry><emphasis>Details</emphasis></entry>
6270 <entry><emphasis>Parameter</emphasis></entry>
6271 <entry><emphasis>Details</emphasis></entry>
6272 <entry><emphasis>Parameter</emphasis></entry>
6273 <entry><emphasis>Details</emphasis></entry>
6274 </row>
6275 </thead>
6276
6277 <tbody>
6278
6279 <!-- native -->
6280 <row>
6281 <?dbhtml bgcolor="#B0B0B0" ?>
6282 <entry namest="c1" nameend="c7">
6283 n_mmap
6284 </entry>
6285 </row>
6286
6287 <row>
6288 <entry>
6289 <classname>std::multimap</classname>
6290 </entry>
6291 <entry namest="c2" nameend="c7"></entry>
6292 </row>
6293
6294 <!-- multimap 01 -->
6295 <row>
6296 <?dbhtml bgcolor="#B0B0B0" ?>
6297 <entry namest="c1" nameend="c7">
6298 rb_tree_mmap_lu_mtf_set
6299 </entry>
6300 </row>
6301
6302 <row>
6303 <entry morerows="2" valign="top">
6304 <classname>tree</classname>
6305 </entry>
6306 <entry>
6307 <classname>Tag</classname>
6308 </entry>
6309 <entry>
6310 <classname>rb_tree_tag</classname>
6311 </entry>
6312 <entry namest="c4" nameend="c7"></entry>
6313 </row>
6314
6315 <row>
6316 <entry>
6317 <classname>Node_Update</classname>
6318 </entry>
6319 <entry>
6320 <classname>null_node_update</classname>
6321 </entry>
6322 <entry namest="c4" nameend="c7"></entry>
6323 </row>
6324 <row>
6325 <entry>
6326 <classname>Mapped</classname>
6327 </entry>
6328 <entry>
6329 <classname>list_update</classname>
6330 </entry>
6331 <entry>
6332 <classname>Update_Policy</classname>
6333 </entry>
6334 <entry>
6335 <classname>lu_move_to_front_policy</classname>
6336 </entry>
6337 <entry namest="c6" nameend="c7"></entry>
6338 </row>
6339
6340 <!-- multimap 02 -->
6341 <row>
6342 <?dbhtml bgcolor="#B0B0B0" ?>
6343 <entry namest="c1" nameend="c7">
6344 rb_tree_mmap_cc_hash_mask_exp_nea_lc_1div8_1div2_nsth_set
6345 </entry>
6346 </row>
6347
6348 <row>
6349 <entry morerows="4" valign="top">
6350 <classname>tree</classname>
6351 </entry>
6352 <entry>
6353 <classname>Tag</classname>
6354 </entry>
6355 <entry>
6356 <classname>rb_tree_tag</classname>
6357 </entry>
6358 <entry namest="c4" nameend="c7"></entry>
6359 </row>
6360
6361 <row>
6362 <entry>
6363 <classname>Node_Update</classname>
6364 </entry>
6365 <entry>
6366 <classname>null_node_update</classname>
6367 </entry>
6368 <entry namest="c4" nameend="c7"></entry>
6369 </row>
6370
6371 <row>
6372 <entry morerows="2" valign="top">
6373 <classname>Mapped</classname>
6374 </entry>
6375 <entry morerows="2" valign="top">
6376 <classname>cc_hash_table</classname>
6377 </entry>
6378 <entry>
6379 <classname>Comb_Hash_Fn</classname>
6380 </entry>
6381 <entry>
6382 <classname>direct_mask_range_hashing</classname>
6383 </entry>
6384 <entry namest="c6" nameend="c7"></entry>
6385 </row>
6386
6387 <row>
6388 <entry morerows="1" valign="top">
6389 <classname>Resize_Policy</classname>
6390 </entry>
6391 <entry morerows="1" valign="top">
6392 <classname>hash_standard_resize_policy</classname>
6393 </entry>
6394 <entry>
6395 <classname>Size_Policy</classname>
6396 </entry>
6397 <entry>
6398 <classname>hash_exponential_size_policy</classname>
6399 </entry>
6400 </row>
6401
6402 <row>
6403 <entry valign="top">
6404 <classname>Trigger_Policy</classname>
6405 </entry>
6406 <entry>
6407 <classname>hash_load_check_resize_trigger</classname> with
6408 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
6409 </entry>
6410 </row>
6411
6412 </tbody>
6413 </tgroup>
6414 </informaltable>
6415
6416
6417 <para>The graphic below show the results for "multimaps" which
6418 use a hash-based container for primary keys.
6419 </para>
6420
6421 <!-- results graphic -->
6422 <informalfigure>
6423 <mediaobject>
6424 <imageobject>
6425 <imagedata align="center" format="PNG" scale="100"
6426 fileref="../images/pbds_multimap_text_find_timing_test_large_s2p_hash_local.png"/>
6427 </imageobject>
6428 <imageobject>
6429 <imagedata align="center" format="PDF" scale="33"
6430 fileref="../images/pbds_multimap_text_find_timing_test_large_s2p_hash_local.pdf"/>
6431 </imageobject>
6432 </mediaobject>
6433 </informalfigure>
6434
6435 <para>
6436 The abbreviated names in the legend of the graphic above are
6437 instantiated with the types in the following table.
6438 </para>
6439
6440 <informaltable frame="all">
6441
6442 <tgroup cols="7" align="left" colsep="1" rowsep="1">
6443 <colspec colname="c1"/>
6444 <colspec colname="c2"/>
6445 <colspec colname="c3"/>
6446 <colspec colname="c4"/>
6447 <colspec colname="c5"/>
6448 <colspec colname="c6"/>
6449 <colspec colname="c7"/>
6450 <thead>
6451 <row>
6452 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
6453 <entry><emphasis>Parameter</emphasis></entry>
6454 <entry><emphasis>Details</emphasis></entry>
6455 <entry><emphasis>Parameter</emphasis></entry>
6456 <entry><emphasis>Details</emphasis></entry>
6457 <entry><emphasis>Parameter</emphasis></entry>
6458 <entry><emphasis>Details</emphasis></entry>
6459 </row>
6460 </thead>
6461
6462 <tbody>
6463
6464 <!-- native -->
6465 <row>
6466 <?dbhtml bgcolor="#B0B0B0" ?>
6467 <entry namest="c1" nameend="c7">
6468 n_hash_mmap
6469 </entry>
6470 </row>
6471
6472 <row>
6473 <entry>
6474 <classname>std::tr1::unordered_multimap</classname>
6475 </entry>
6476 <entry namest="c2" nameend="c7"></entry>
6477 </row>
6478
6479 <!-- multimap 01 -->
6480 <row>
6481 <?dbhtml bgcolor="#B0B0B0" ?>
6482 <entry namest="c1" nameend="c7">
6483 rb_tree_mmap_lu_mtf_set
6484 </entry>
6485 </row>
6486
6487 <row>
6488 <entry morerows="3" valign="top">
6489 <classname>
6490 cc_hash_table
6491 </classname>
6492 </entry>
6493 <entry>
6494 <classname>Comb_Hash_Fn</classname>
6495 </entry>
6496 <entry>
6497 <classname>direct_mask_range_hashing</classname>
6498 </entry>
6499 <entry namest="c4" nameend="c7"></entry>
6500 </row>
6501 <row>
6502 <entry morerows="1" valign="top">
6503 <classname>Resize_Policy</classname>
6504 </entry>
6505 <entry morerows="1" valign="top">
6506 <classname>hash_standard_resize_policy</classname>
6507 </entry>
6508 <entry>
6509 <classname>Size_Policy</classname>
6510 </entry>
6511 <entry>
6512 <classname>hash_exponential_size_policy</classname>
6513 </entry>
6514 <entry namest="c6" nameend="c7"></entry>
6515 </row>
6516
6517 <row>
6518 <entry valign="top">
6519 <classname>Trigger_Policy</classname>
6520 </entry>
6521 <entry>
6522 <classname>hash_load_check_resize_trigger</classname> with
6523 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
6524 </entry>
6525 <entry namest="c6" nameend="c7"></entry>
6526 </row>
6527
6528 <row>
6529 <entry>
6530 <classname>Mapped</classname>
6531 </entry>
6532 <entry>
6533 <classname>list_update</classname>
6534 </entry>
6535 <entry>
6536 <classname>Update_Policy</classname>
6537 </entry>
6538 <entry>
6539 <classname>lu_move_to_front_policy</classname>
6540 </entry>
6541 <entry namest="c6" nameend="c7"></entry>
6542 </row>
6543
6544 <!-- multimap 02 -->
6545 <row>
6546 <?dbhtml bgcolor="#B0B0B0" ?>
6547 <entry namest="c1" nameend="c7">
6548 rb_tree_mmap_cc_hash_mask_exp_nea_lc_1div8_1div2_nsth_set
6549 </entry>
6550 </row>
6551
6552 <row>
6553 <entry morerows="5" valign="top">
6554 <classname>
6555 cc_hash_table
6556 </classname>
6557 </entry>
6558 <entry>
6559 <classname>Comb_Hash_Fn</classname>
6560 </entry>
6561 <entry>
6562 <classname>direct_mask_range_hashing</classname>
6563 </entry>
6564 <entry namest="c4" nameend="c7"></entry>
6565 </row>
6566 <row>
6567 <entry morerows="1" valign="top">
6568 <classname>Resize_Policy</classname>
6569 </entry>
6570 <entry morerows="1" valign="top">
6571 <classname>hash_standard_resize_policy</classname>
6572 </entry>
6573 <entry>
6574 <classname>Size_Policy</classname>
6575 </entry>
6576 <entry>
6577 <classname>hash_exponential_size_policy</classname>
6578 </entry>
6579 <entry namest="c6" nameend="c7"></entry>
6580 </row>
6581
6582 <row>
6583 <entry valign="top">
6584 <classname>Trigger_Policy</classname>
6585 </entry>
6586 <entry>
6587 <classname>hash_load_check_resize_trigger</classname> with
6588 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
6589 </entry>
6590 <entry namest="c6" nameend="c7"></entry>
6591 </row>
6592
6593 <row>
6594 <entry morerows="2" valign="top">
6595 <classname>Mapped</classname>
6596 </entry>
6597 <entry morerows="2" valign="top">
6598 <classname>cc_hash_table</classname>
6599 </entry>
6600 <entry>
6601 <classname>Comb_Hash_Fn</classname>
6602 </entry>
6603 <entry>
6604 <classname>direct_mask_range_hashing</classname>
6605 </entry>
6606 <entry namest="c6" nameend="c7"></entry>
6607 </row>
6608
6609 <row>
6610 <entry morerows="1" valign="top">
6611 <classname>Resize_Policy</classname>
6612 </entry>
6613 <entry morerows="1" valign="top">
6614 <classname>hash_standard_resize_policy</classname>
6615 </entry>
6616 <entry>
6617 <classname>Size_Policy</classname>
6618 </entry>
6619 <entry>
6620 <classname>hash_exponential_size_policy</classname>
6621 </entry>
6622 </row>
6623
6624 <row>
6625 <entry valign="top">
6626 <classname>Trigger_Policy</classname>
6627 </entry>
6628 <entry>
6629 <classname>hash_load_check_resize_trigger</classname> with
6630 α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2
6631 </entry>
6632 </row>
6633
6634 </tbody>
6635 </tgroup>
6636 </informaltable>
6637
6638 </section>
6639
6640 <section xml:id="multimap.text_insert_mem_large.observations">
6641 <info><title>
6642 Observations
6643 </title></info>
6644
6645 <para>See Observations::Mapping-Semantics
6646 Considerations.</para>
6647
6648 </section>
6649
6650 </section>
6651
6652 </section> <!-- multimap -->
6653
6654 <section xml:id="performance.priority_queue">
6655 <info><title>Priority Queue</title></info>
6656
6657 <!-- 01 <a href="priority_queue_text_push_timing_test"> -->
6658 <section xml:id="performance.priority_queue.text_push">
6659 <info><title>
6660 Text <function>push</function>
6661 </title></info>
6662 <para></para>
6663
6664 <section xml:id="priority_queue.text_push.info">
6665 <info><title>
6666 Description
6667 </title></info>
6668
6669
6670 <para>This test inserts a number of values with keys from an
6671 arbitrary text ([ wickland96thirty ]) into
6672 a container using <function>push</function>. It measures the average time
6673 for <function>push</function> as a function of the number of values
6674 pushed.</para>
6675
6676 <para>
6677 It uses the test file:
6678 <filename>
6679 performance/ext/pb_ds/priority_queue_text_push_timing.cc
6680 </filename>
6681 </para>
6682
6683 <para>The test checks the effect of different underlying data
6684 structures.
6685 </para>
6686
6687 </section>
6688
6689 <section xml:id="priority_queue.text_push.results">
6690 <info><title>
6691 Results
6692 </title></info>
6693
6694 <para>The two graphics below show the results for the native
6695 priority_queues and this library's priority_queues.
6696 </para>
6697
6698 <para>The graphic immediately below shows the results for the
6699 native priority_queue type instantiated with different underlying
6700 container types versus several different versions of library's
6701 priority_queues.
6702 </para>
6703
6704 <!-- results graphic -->
6705 <informalfigure>
6706 <mediaobject>
6707 <imageobject>
6708 <imagedata align="center" format="PDF" scale="75"
6709 fileref="../images/pbds_priority_queue_text_push_timing_test_local.pdf"/>
6710 </imageobject>
6711 <imageobject>
6712 <imagedata align="center" format="PNG" scale="100"
6713 fileref="../images/pbds_priority_queue_text_push_timing_test_local.png"/>
6714 </imageobject>
6715 </mediaobject>
6716 </informalfigure>
6717
6718 <para>
6719 The abbreviated names in the legend of the graphic above are
6720 instantiated with the types in the following table.
6721 </para>
6722
6723
6724 <informaltable frame="all">
6725
6726 <tgroup cols="3" align="left" colsep="1" rowsep="1">
6727 <colspec colname="c1"/>
6728 <colspec colname="c2"/>
6729 <colspec colname="c3"/>
6730 <thead>
6731 <row>
6732 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
6733 <entry><emphasis>Parameter</emphasis></entry>
6734 <entry><emphasis>Details</emphasis></entry>
6735 </row>
6736 </thead>
6737
6738 <tbody>
6739
6740 <!-- native 01 -->
6741 <row>
6742 <?dbhtml bgcolor="#B0B0B0" ?>
6743 <entry namest="c1" nameend="c3">
6744 n_pq_vector
6745 </entry>
6746 </row>
6747
6748 <row>
6749 <entry>
6750 <classname>std::priority_queue</classname>
6751 </entry>
6752 <entry>
6753 <classname>Sequence</classname>
6754 </entry>
6755 <entry>
6756 <classname>std::vector</classname>
6757 </entry>
6758 </row>
6759
6760 <!-- native 02 -->
6761 <row>
6762 <?dbhtml bgcolor="#B0B0B0" ?>
6763 <entry namest="c1" nameend="c3">
6764 n_pq_deque
6765 </entry>
6766 </row>
6767
6768 <row>
6769 <entry>
6770 <classname>std::priority_queue</classname>
6771 </entry>
6772 <entry>
6773 <classname>Sequence</classname>
6774 </entry>
6775 <entry>
6776 <classname>std::deque</classname>
6777 </entry>
6778 </row>
6779
6780 <!-- priority_queue 01 -->
6781 <row>
6782 <?dbhtml bgcolor="#B0B0B0" ?>
6783 <entry namest="c1" nameend="c3">
6784 binary_heap
6785 </entry>
6786 </row>
6787
6788 <row>
6789 <entry>
6790 <classname>priority_queue</classname>
6791 </entry>
6792 <entry>
6793 <classname>Tag</classname>
6794 </entry>
6795 <entry>
6796 <classname>binary_heap_tag</classname>
6797 </entry>
6798 </row>
6799
6800 <!-- priority_queue 02 -->
6801 <row>
6802 <?dbhtml bgcolor="#B0B0B0" ?>
6803 <entry namest="c1" nameend="c3">
6804 binomial_heap
6805 </entry>
6806 </row>
6807
6808 <row>
6809 <entry>
6810 <classname>priority_queue</classname>
6811 </entry>
6812 <entry>
6813 <classname>Tag</classname>
6814 </entry>
6815 <entry>
6816 <classname>binomial_heap_tag</classname>
6817 </entry>
6818 </row>
6819
6820 <!-- priority_queue 03 -->
6821 <row>
6822 <?dbhtml bgcolor="#B0B0B0" ?>
6823 <entry namest="c1" nameend="c3">
6824 rc_binomial_heap
6825 </entry>
6826 </row>
6827
6828 <row>
6829 <entry>
6830 <classname>priority_queue</classname>
6831 </entry>
6832 <entry>
6833 <classname>Tag</classname>
6834 </entry>
6835 <entry>
6836 <classname>rc_binomial_heap_tag</classname>
6837 </entry>
6838 </row>
6839
6840 <!-- priority_queue 04 -->
6841 <row>
6842 <?dbhtml bgcolor="#B0B0B0" ?>
6843 <entry namest="c1" nameend="c3">
6844 thin_heap
6845 </entry>
6846 </row>
6847
6848 <row>
6849 <entry>
6850 <classname>priority_queue</classname>
6851 </entry>
6852 <entry>
6853 <classname>Tag</classname>
6854 </entry>
6855 <entry>
6856 <classname>thin_heap_tag</classname>
6857 </entry>
6858 </row>
6859
6860
6861 <!-- priority_queue 05 -->
6862 <row>
6863 <?dbhtml bgcolor="#B0B0B0" ?>
6864 <entry namest="c1" nameend="c3">
6865 pairing_heap
6866 </entry>
6867 </row>
6868
6869 <row>
6870 <entry>
6871 <classname>priority_queue</classname>
6872 </entry>
6873 <entry>
6874 <classname>Tag</classname>
6875 </entry>
6876 <entry>
6877 <classname>pairing_heap_tag</classname>
6878 </entry>
6879 </row>
6880
6881 </tbody>
6882 </tgroup>
6883 </informaltable>
6884
6885
6886
6887 <para>The graphic below shows the results for the binary-heap
6888 based native priority queues and this library's pairing-heap
6889 priority_queue data structures.
6890 </para>
6891
6892 <!-- results graphic -->
6893 <informalfigure>
6894 <mediaobject>
6895 <imageobject>
6896 <imagedata align="center" format="PDF" scale="75"
6897 fileref="../images/pbds_pairing_priority_queue_text_push_timing_test_local.pdf"/>
6898 </imageobject>
6899 <imageobject>
6900 <imagedata align="center" format="PNG" scale="100"
6901 fileref="../images/pbds_pairing_priority_queue_text_push_timing_test_local.png"/>
6902 </imageobject>
6903 </mediaobject>
6904 </informalfigure>
6905
6906 <para>
6907 The abbreviated names in the legend of the graphic above are
6908 instantiated with the types in the following table.
6909 </para>
6910
6911
6912 <informaltable frame="all">
6913
6914 <tgroup cols="3" align="left" colsep="1" rowsep="1">
6915 <colspec colname="c1"/>
6916 <colspec colname="c2"/>
6917 <colspec colname="c3"/>
6918 <thead>
6919 <row>
6920 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
6921 <entry><emphasis>Parameter</emphasis></entry>
6922 <entry><emphasis>Details</emphasis></entry>
6923 </row>
6924 </thead>
6925
6926 <tbody>
6927 <!-- native 01 -->
6928 <row>
6929 <?dbhtml bgcolor="#B0B0B0" ?>
6930 <entry namest="c1" nameend="c3">
6931 n_pq_vector
6932 </entry>
6933 </row>
6934
6935 <row>
6936 <entry>
6937 <classname>std::priority_queue</classname>
6938 </entry>
6939 <entry>
6940 <classname>Sequence</classname>
6941 </entry>
6942 <entry>
6943 <classname>std::vector</classname>
6944 </entry>
6945 </row>
6946
6947 <!-- native 02 -->
6948 <row>
6949 <?dbhtml bgcolor="#B0B0B0" ?>
6950 <entry namest="c1" nameend="c3">
6951 n_pq_deque
6952 </entry>
6953 </row>
6954
6955 <row>
6956 <entry>
6957 <classname>std::priority_queue</classname>
6958 </entry>
6959 <entry>
6960 <classname>Sequence</classname>
6961 </entry>
6962 <entry>
6963 <classname>std::deque</classname>
6964 </entry>
6965
6966 </row>
6967
6968 <!-- priority_queue 01 -->
6969 <row>
6970 <?dbhtml bgcolor="#B0B0B0" ?>
6971 <entry namest="c1" nameend="c3">
6972 thin_heap
6973 </entry>
6974 </row>
6975
6976 <row>
6977 <entry>
6978 <classname>priority_queue</classname>
6979 </entry>
6980 <entry>
6981 <classname>Tag</classname>
6982 </entry>
6983 <entry>
6984 <classname>thin_heap_tag</classname>
6985 </entry>
6986 </row>
6987
6988
6989 <!-- priority_queue 02 -->
6990 <row>
6991 <?dbhtml bgcolor="#B0B0B0" ?>
6992 <entry namest="c1" nameend="c3">
6993 pairing_heap
6994 </entry>
6995 </row>
6996
6997 <row>
6998 <entry>
6999 <classname>priority_queue</classname>
7000 </entry>
7001 <entry>
7002 <classname>Tag</classname>
7003 </entry>
7004 <entry>
7005 <classname>pairing_heap_tag</classname>
7006 </entry>
7007 </row>
7008
7009 </tbody>
7010 </tgroup>
7011 </informaltable>
7012
7013
7014 </section>
7015
7016 <section xml:id="priority_queue.text_push.observations">
7017 <info><title>
7018 Observations
7019 </title></info>
7020
7021 <para>Pairing heaps (<classname>priority_queue</classname> with
7022 <classname>Tag</classname> = <classname>pairing_heap_tag</classname>)
7023 are the most suited for sequences of <function>push</function> and
7024 <function>pop</function> operations of non-primitive types (e.g.
7025 <classname>std::string</classname>s). (See Priority Queue
7026 Text <function>push</function> and <function>pop</function> Timing Test.) They are
7027 less constrained than binomial heaps, e.g., and since
7028 they are node-based, they outperform binary heaps. (See
7029 Priority
7030 Queue Random Integer <function>push</function> Timing Test for the case
7031 of primitive types.)</para>
7032
7033 <para>The standard's priority queues do not seem to perform well in
7034 this case: the <classname>std::vector</classname> implementation needs to
7035 perform a logarithmic sequence of string operations for each
7036 operation, and the deque implementation is possibly hampered by
7037 its need to manipulate a relatively-complex type (deques
7038 support a O(1) <function>push_front</function>, even though it is
7039 not used by <classname>std::priority_queue</classname>.)</para>
7040
7041 </section>
7042 </section>
7043
7044 <!-- 02 <a href="priority_queue_text_push_pop_timing_test"> -->
7045 <section xml:id="performance.priority_queue.text_push_pop">
7046 <info><title>
7047 Text <function>push</function> and <function>pop</function>
7048 </title></info>
7049 <para></para>
7050
7051 <section xml:id="priority_queue.text_push_pop.info">
7052 <info><title>
7053 Description
7054 </title></info>
7055
7056 <para>This test inserts a number of values with keys from an
7057 arbitrary text ([ wickland96thirty ]) into
7058 a container using <classname>push</classname> , then removes them using
7059 <classname>pop</classname> . It measures the average time for <classname>push</classname>
7060 as a function of the number of values.</para>
7061
7062
7063 <para>
7064 It uses the test file:
7065 <filename>
7066 performance/ext/pb_ds/priority_queue_text_push_pop_timing.cc
7067 </filename>
7068 </para>
7069
7070 <para>The test checks the effect of different underlying data
7071 structures.
7072 </para>
7073
7074 </section>
7075
7076 <section xml:id="priority_queue.text_push_pop.results">
7077 <info><title>
7078 Results
7079 </title></info>
7080
7081 <para>The two graphics below show the results for the native
7082 priority_queues and this library's priority_queues.
7083 </para>
7084
7085 <para>The graphic immediately below shows the results for the
7086 native priority_queue type instantiated with different underlying
7087 container types versus several different versions of library's
7088 priority_queues.
7089 </para>
7090
7091 <!-- results graphic -->
7092 <informalfigure>
7093 <mediaobject>
7094 <imageobject>
7095 <imagedata align="center" format="PDF" scale="75"
7096 fileref="../images/pbds_priority_queue_text_push_pop_timing_test_local.pdf"/>
7097 </imageobject>
7098 <imageobject>
7099 <imagedata align="center" format="PNG" scale="100"
7100 fileref="../images/pbds_priority_queue_text_push_pop_timing_test_local.png"/>
7101 </imageobject>
7102 </mediaobject>
7103 </informalfigure>
7104
7105 <para>
7106 The abbreviated names in the legend of the graphic above are
7107 instantiated with the types in the following table.
7108 </para>
7109
7110
7111 <informaltable frame="all">
7112
7113 <tgroup cols="3" align="left" colsep="1" rowsep="1">
7114 <colspec colname="c1"/>
7115 <colspec colname="c2"/>
7116 <colspec colname="c3"/>
7117 <thead>
7118 <row>
7119 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
7120 <entry><emphasis>Parameter</emphasis></entry>
7121 <entry><emphasis>Details</emphasis></entry>
7122 </row>
7123 </thead>
7124
7125 <tbody>
7126
7127 <!-- native 01 -->
7128 <row>
7129 <?dbhtml bgcolor="#B0B0B0" ?>
7130 <entry namest="c1" nameend="c3">
7131 n_pq_vector
7132 </entry>
7133 </row>
7134
7135 <row>
7136 <entry>
7137 <classname>std::priority_queue</classname>
7138 </entry>
7139 <entry>
7140 <classname>Sequence</classname>
7141 </entry>
7142 <entry>
7143 <classname>std::vector</classname>
7144 </entry>
7145 </row>
7146
7147 <!-- native 02 -->
7148 <row>
7149 <?dbhtml bgcolor="#B0B0B0" ?>
7150 <entry namest="c1" nameend="c3">
7151 n_pq_deque
7152 </entry>
7153 </row>
7154
7155 <row>
7156 <entry>
7157 <classname>std::priority_queue</classname>
7158 </entry>
7159 <entry>
7160 <classname>Sequence</classname>
7161 </entry>
7162 <entry>
7163 <classname>std::deque</classname>
7164 </entry>
7165
7166 </row>
7167
7168 <!-- priority_queue 01 -->
7169 <row>
7170 <?dbhtml bgcolor="#B0B0B0" ?>
7171 <entry namest="c1" nameend="c3">
7172 binary_heap
7173 </entry>
7174 </row>
7175
7176 <row>
7177 <entry>
7178 <classname>priority_queue</classname>
7179 </entry>
7180 <entry>
7181 <classname>Tag</classname>
7182 </entry>
7183 <entry>
7184 <classname>binary_heap_tag</classname>
7185 </entry>
7186 </row>
7187
7188 <!-- priority_queue 02 -->
7189 <row>
7190 <?dbhtml bgcolor="#B0B0B0" ?>
7191 <entry namest="c1" nameend="c3">
7192 binomial_heap
7193 </entry>
7194 </row>
7195
7196 <row>
7197 <entry>
7198 <classname>priority_queue</classname>
7199 </entry>
7200 <entry>
7201 <classname>Tag</classname>
7202 </entry>
7203 <entry>
7204 <classname>binomial_heap_tag</classname>
7205 </entry>
7206 </row>
7207
7208 <!-- priority_queue 03 -->
7209 <row>
7210 <?dbhtml bgcolor="#B0B0B0" ?>
7211 <entry namest="c1" nameend="c3">
7212 rc_binomial_heap
7213 </entry>
7214 </row>
7215
7216 <row>
7217 <entry>
7218 <classname>priority_queue</classname>
7219 </entry>
7220 <entry>
7221 <classname>Tag</classname>
7222 </entry>
7223 <entry>
7224 <classname>rc_binomial_heap_tag</classname>
7225 </entry>
7226 </row>
7227
7228 <!-- priority_queue 04 -->
7229 <row>
7230 <?dbhtml bgcolor="#B0B0B0" ?>
7231 <entry namest="c1" nameend="c3">
7232 thin_heap
7233 </entry>
7234 </row>
7235
7236 <row>
7237 <entry>
7238 <classname>priority_queue</classname>
7239 </entry>
7240 <entry>
7241 <classname>Tag</classname>
7242 </entry>
7243 <entry>
7244 <classname>thin_heap_tag</classname>
7245 </entry>
7246 </row>
7247
7248 <!-- priority_queue 05 -->
7249 <row>
7250 <?dbhtml bgcolor="#B0B0B0" ?>
7251 <entry namest="c1" nameend="c3">
7252 pairing_heap
7253 </entry>
7254 </row>
7255
7256 <row>
7257 <entry>
7258 <classname>priority_queue</classname>
7259 </entry>
7260 <entry>
7261 <classname>Tag</classname>
7262 </entry>
7263 <entry>
7264 <classname>pairing_heap_tag</classname>
7265 </entry>
7266 </row>
7267
7268 </tbody>
7269 </tgroup>
7270 </informaltable>
7271
7272
7273
7274 <para>The graphic below shows the results for the native priority
7275 queues and this library's pairing-heap priority_queue data
7276 structures.
7277 </para>
7278
7279 <!-- results graphic -->
7280 <informalfigure>
7281 <mediaobject>
7282 <imageobject>
7283 <imagedata align="center" format="PDF" scale="75"
7284 fileref="../images/pbds_pairing_priority_queue_text_push_pop_timing_test_local.pdf"/>
7285 </imageobject>
7286 <imageobject>
7287 <imagedata align="center" format="PNG" scale="100"
7288 fileref="../images/pbds_pairing_priority_queue_text_push_pop_timing_test_local.png"/>
7289 </imageobject>
7290 </mediaobject>
7291 </informalfigure>
7292
7293 <para>
7294 The abbreviated names in the legend of the graphic above are
7295 instantiated with the types in the following table.
7296 </para>
7297
7298
7299 <informaltable frame="all">
7300
7301 <tgroup cols="3" align="left" colsep="1" rowsep="1">
7302 <colspec colname="c1"/>
7303 <colspec colname="c2"/>
7304 <colspec colname="c3"/>
7305 <thead>
7306 <row>
7307 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
7308 <entry><emphasis>Parameter</emphasis></entry>
7309 <entry><emphasis>Details</emphasis></entry>
7310 </row>
7311 </thead>
7312
7313 <tbody>
7314
7315 <!-- native 01 -->
7316 <row>
7317 <?dbhtml bgcolor="#B0B0B0" ?>
7318 <entry namest="c1" nameend="c3">
7319 n_pq_vector
7320 </entry>
7321 </row>
7322
7323 <row>
7324 <entry>
7325 <classname>std::priority_queue</classname> adapting <classname>std::vector</classname>
7326 </entry>
7327 <entry>
7328 <classname>Sequence</classname>
7329 </entry>
7330 <entry>
7331 <classname>std::vector</classname>
7332 </entry>
7333
7334 </row>
7335
7336 <!-- native 02 -->
7337 <row>
7338 <?dbhtml bgcolor="#B0B0B0" ?>
7339 <entry namest="c1" nameend="c3">
7340 n_pq_deque
7341 </entry>
7342 </row>
7343
7344 <row>
7345 <entry>
7346 <classname>std::priority_queue</classname>
7347 </entry>
7348 <entry>
7349 <classname>Sequence</classname>
7350 </entry>
7351 <entry>
7352 <classname>std::deque</classname>
7353 </entry>
7354
7355 </row>
7356
7357 <!-- priority_queue 01 -->
7358 <row>
7359 <?dbhtml bgcolor="#B0B0B0" ?>
7360 <entry namest="c1" nameend="c3">
7361 pairing_heap
7362 </entry>
7363 </row>
7364
7365 <row>
7366 <entry>
7367 <classname>priority_queue</classname>
7368 </entry>
7369 <entry>
7370 <classname>Tag</classname>
7371 </entry>
7372 <entry>
7373 <classname>pairing_heap_tag</classname>
7374 </entry>
7375 </row>
7376
7377 </tbody>
7378 </tgroup>
7379 </informaltable>
7380
7381
7382 </section>
7383
7384 <section xml:id="priority_queue.text_push_pop.observations">
7385 <info><title>
7386 Observations
7387 </title></info>
7388
7389 <para>These results are very similar to Priority Queue Text
7390 <function>push</function> Timing Test. As stated there, pairing heaps
7391 (<classname>priority_queue</classname> with
7392 <classname>Tag</classname>
7393 = <classname>pairing_heap_tag</classname>) are most suited
7394 for <function>push</function> and <function>pop</function>
7395 sequences of non-primitive types such as strings. Observing these
7396 two tests, one can note that a pairing heap outperforms the others
7397 in terms of <function>push</function> operations, but equals
7398 binary heaps (<classname>priority_queue</classname> with
7399 <classname>Tag</classname>
7400 = <classname>binary_heap_tag</classname>) if the number
7401 of <function>push</function> and <function>pop</function>
7402 operations is equal. As the number of <function>pop</function>
7403 operations is at most equal to the number
7404 of <function>push</function> operations, pairing heaps are better
7405 in this case. See Priority Queue Random
7406 Integer <function>push</function> and <function>pop</function>
7407 Timing Test for a case which is different.</para>
7408
7409 </section>
7410 </section>
7411
7412
7413 <!-- 03 <a href="priority_queue_random_int_push_timing_test"> -->
7414 <section xml:id="performance.priority_queue.int_push">
7415 <info><title>
7416 Integer <function>push</function>
7417 </title></info>
7418 <para></para>
7419
7420 <section xml:id="priority_queue.int_push.info">
7421 <info><title>
7422 Description
7423 </title></info>
7424
7425 <para>This test inserts a number of values with integer keys
7426 into a container using <function>push</function>. It
7427 measures the average time for <function>push</function> as a
7428 function of the number of values.</para>
7429
7430 <para>
7431 It uses the test file:
7432 <filename>
7433 performance/ext/pb_ds/priority_queue_random_int_push_timing.cc
7434 </filename>
7435 </para>
7436
7437 <para>The test checks the effect of different underlying data
7438 structures.
7439 </para>
7440
7441 </section>
7442
7443 <section xml:id="priority_queue.int_push.results">
7444 <info><title>
7445 Results
7446 </title></info>
7447
7448 <para>The two graphics below show the results for the native
7449 priority_queues and this library's priority_queues.
7450 </para>
7451
7452 <para>The graphic immediately below shows the results for the
7453 native priority_queue type instantiated with different underlying
7454 container types versus several different versions of library's
7455 priority_queues.
7456 </para>
7457
7458 <!-- results graphic -->
7459 <informalfigure>
7460 <mediaobject>
7461 <imageobject>
7462 <imagedata align="center" format="PDF" scale="75"
7463 fileref="../images/pbds_priority_queue_random_int_push_timing_test_local.pdf"/>
7464 </imageobject>
7465 <imageobject>
7466 <imagedata align="center" format="PNG" scale="100"
7467 fileref="../images/pbds_priority_queue_random_int_push_timing_test_local.png"/>
7468 </imageobject>
7469 </mediaobject>
7470 </informalfigure>
7471
7472 <para>
7473 The abbreviated names in the legend of the graphic above are
7474 instantiated with the types in the following table.
7475 </para>
7476
7477
7478 <informaltable frame="all">
7479
7480 <tgroup cols="3" align="left" colsep="1" rowsep="1">
7481 <colspec colname="c1"/>
7482 <colspec colname="c2"/>
7483 <colspec colname="c3"/>
7484 <thead>
7485 <row>
7486 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
7487 <entry><emphasis>Parameter</emphasis></entry>
7488 <entry><emphasis>Details</emphasis></entry>
7489 </row>
7490 </thead>
7491
7492 <tbody>
7493
7494 <!-- native 01 -->
7495 <row>
7496 <?dbhtml bgcolor="#B0B0B0" ?>
7497 <entry namest="c1" nameend="c3">
7498 n_pq_vector
7499 </entry>
7500 </row>
7501
7502 <row>
7503 <entry>
7504 <classname>std::priority_queue</classname>
7505 </entry>
7506 <entry>
7507 <classname>Sequence</classname>
7508 </entry>
7509 <entry>
7510 <classname>std::vector</classname>
7511 </entry>
7512 </row>
7513
7514 <!-- native 02 -->
7515 <row>
7516 <?dbhtml bgcolor="#B0B0B0" ?>
7517 <entry namest="c1" nameend="c3">
7518 n_pq_deque
7519 </entry>
7520 </row>
7521
7522 <row>
7523 <entry>
7524 <classname>std::priority_queue</classname>
7525 </entry>
7526 <entry>
7527 <classname>Sequence</classname>
7528 </entry>
7529 <entry>
7530 <classname>std::deque</classname>
7531 </entry>
7532
7533 </row>
7534
7535 <!-- priority_queue 01 -->
7536 <row>
7537 <?dbhtml bgcolor="#B0B0B0" ?>
7538 <entry namest="c1" nameend="c3">
7539 binary_heap
7540 </entry>
7541 </row>
7542
7543 <row>
7544 <entry>
7545 <classname>priority_queue</classname>
7546 </entry>
7547 <entry>
7548 <classname>Tag</classname>
7549 </entry>
7550 <entry>
7551 <classname>binary_heap_tag</classname>
7552 </entry>
7553 </row>
7554
7555 <!-- priority_queue 02 -->
7556 <row>
7557 <?dbhtml bgcolor="#B0B0B0" ?>
7558 <entry namest="c1" nameend="c3">
7559 binomial_heap
7560 </entry>
7561 </row>
7562
7563 <row>
7564 <entry>
7565 <classname>priority_queue</classname>
7566 </entry>
7567 <entry>
7568 <classname>Tag</classname>
7569 </entry>
7570 <entry>
7571 <classname>binomial_heap_tag</classname>
7572 </entry>
7573 </row>
7574
7575 <!-- priority_queue 03 -->
7576 <row>
7577 <?dbhtml bgcolor="#B0B0B0" ?>
7578 <entry namest="c1" nameend="c3">
7579 rc_binomial_heap
7580 </entry>
7581 </row>
7582
7583 <row>
7584 <entry>
7585 <classname>priority_queue</classname>
7586 </entry>
7587 <entry>
7588 <classname>Tag</classname>
7589 </entry>
7590 <entry>
7591 <classname>rc_binomial_heap_tag</classname>
7592 </entry>
7593 </row>
7594
7595 <!-- priority_queue 04 -->
7596 <row>
7597 <?dbhtml bgcolor="#B0B0B0" ?>
7598 <entry namest="c1" nameend="c3">
7599 thin_heap
7600 </entry>
7601 </row>
7602
7603 <row>
7604 <entry>
7605 <classname>priority_queue</classname>
7606 </entry>
7607 <entry>
7608 <classname>Tag</classname>
7609 </entry>
7610 <entry>
7611 <classname>thin_heap_tag</classname>
7612 </entry>
7613 </row>
7614
7615 <!-- priority_queue 05 -->
7616 <row>
7617 <?dbhtml bgcolor="#B0B0B0" ?>
7618 <entry namest="c1" nameend="c3">
7619 pairing_heap
7620 </entry>
7621 </row>
7622
7623 <row>
7624 <entry>
7625 <classname>priority_queue</classname>
7626 </entry>
7627 <entry>
7628 <classname>Tag</classname>
7629 </entry>
7630 <entry>
7631 <classname>pairing_heap_tag</classname>
7632 </entry>
7633 </row>
7634
7635 </tbody>
7636 </tgroup>
7637 </informaltable>
7638
7639
7640
7641 <para>The graphic below shows the results for the binary-heap
7642 based native priority queues and this library's
7643 priority_queue data structures.
7644 </para>
7645
7646 <!-- results graphic -->
7647 <informalfigure>
7648 <mediaobject>
7649 <imageobject>
7650 <imagedata align="center" format="PDF" scale="75"
7651 fileref="../images/pbds_binary_priority_queue_random_int_push_timing_test_local.pdf"/>
7652 </imageobject>
7653 <imageobject>
7654 <imagedata align="center" format="PNG" scale="100"
7655 fileref="../images/pbds_binary_priority_queue_random_int_push_timing_test_local.png"/>
7656 </imageobject>
7657 </mediaobject>
7658 </informalfigure>
7659
7660 <para>
7661 The abbreviated names in the legend of the graphic above are
7662 instantiated with the types in the following table.
7663 </para>
7664
7665
7666 <informaltable frame="all">
7667
7668 <tgroup cols="3" align="left" colsep="1" rowsep="1">
7669 <colspec colname="c1"/>
7670 <colspec colname="c2"/>
7671 <colspec colname="c3"/>
7672 <thead>
7673 <row>
7674 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
7675 <entry><emphasis>Parameter</emphasis></entry>
7676 <entry><emphasis>Details</emphasis></entry>
7677 </row>
7678 </thead>
7679
7680 <tbody>
7681
7682 <!-- native 01 -->
7683 <row>
7684 <?dbhtml bgcolor="#B0B0B0" ?>
7685 <entry namest="c1" nameend="c3">
7686 n_pq_vector
7687 </entry>
7688 </row>
7689
7690 <row>
7691 <entry>
7692 <classname>std::priority_queue</classname> adapting <classname>std::vector</classname>
7693 </entry>
7694 <entry>
7695 <classname>Sequence</classname>
7696 </entry>
7697 <entry>
7698 <classname>std::vector</classname>
7699 </entry>
7700
7701 </row>
7702
7703 <!-- native 02 -->
7704 <row>
7705 <?dbhtml bgcolor="#B0B0B0" ?>
7706 <entry namest="c1" nameend="c3">
7707 n_pq_deque
7708 </entry>
7709 </row>
7710
7711 <row>
7712 <entry>
7713 <classname>std::priority_queue</classname>
7714 </entry>
7715 <entry>
7716 <classname>Sequence</classname>
7717 </entry>
7718 <entry>
7719 <classname>std::deque</classname>
7720 </entry>
7721
7722 </row>
7723
7724 <!-- priority_queue 01 -->
7725 <row>
7726 <?dbhtml bgcolor="#B0B0B0" ?>
7727 <entry namest="c1" nameend="c3">
7728 binary_heap
7729 </entry>
7730 </row>
7731
7732 <row>
7733 <entry>
7734 <classname>priority_queue</classname>
7735 </entry>
7736 <entry>
7737 <classname>Tag</classname>
7738 </entry>
7739 <entry>
7740 <classname>binary_heap_tag</classname>
7741 </entry>
7742 </row>
7743
7744 </tbody>
7745 </tgroup>
7746 </informaltable>
7747
7748
7749 </section>
7750
7751 <section xml:id="priority_queue.int_push.observations">
7752 <info><title>
7753 Observations
7754 </title></info>
7755
7756
7757 <para>Binary heaps are the most suited for sequences of
7758 <function>push</function> and <function>pop</function> operations of primitive types
7759 (e.g. <type>int</type>s). They are less constrained
7760 than any other type, and since it is very efficient to store
7761 such types in arrays, they outperform even pairing heaps. (See
7762 Priority
7763 Queue Text <function>push</function> Timing Test for the case of
7764 non-primitive types.)</para>
7765 </section>
7766 </section>
7767
7768 <!-- 04 "priority_queue_random_int_push_pop_timing_test" -->
7769 <section xml:id="performance.priority_queue.int_push_pop">
7770 <info><title>
7771 Integer <function>push</function>
7772 </title></info>
7773 <para></para>
7774
7775 <section xml:id="priority_queue.int_push_pop.info">
7776 <info><title>
7777 Description
7778 </title></info>
7779
7780 <para>This test inserts a number of values with integer keys
7781 into a container using <function>push</function> , then removes them
7782 using <function>pop</function> . It measures the average time for
7783 <function>push</function> and <function>pop</function> as a function
7784 of the number of values.</para>
7785
7786 <para>
7787 It uses the test file:
7788 <filename>
7789 performance/ext/pb_ds/priority_queue_random_int_push_pop_timing.cc
7790 </filename>
7791 </para>
7792
7793 <para>The test checks the effect of different underlying data
7794 structures.
7795 </para>
7796
7797 </section>
7798
7799 <section xml:id="priority_queue.int_push_pop.results">
7800 <info><title>
7801 Results
7802 </title></info>
7803
7804 <para>The graphic immediately below shows the results for the
7805 native priority_queue type instantiated with different underlying
7806 container types versus several different versions of library's
7807 priority_queues.
7808 </para>
7809
7810 <!-- results graphic -->
7811 <informalfigure>
7812 <mediaobject>
7813 <imageobject>
7814 <imagedata align="center" format="PDF" scale="75"
7815 fileref="../images/pbds_priority_queue_random_int_push_pop_timing_test_local.pdf"/>
7816 </imageobject>
7817 <imageobject>
7818 <imagedata align="center" format="PNG" scale="100"
7819 fileref="../images/pbds_priority_queue_random_int_push_pop_timing_test_local.png"/>
7820 </imageobject>
7821 </mediaobject>
7822 </informalfigure>
7823
7824 <para>
7825 The abbreviated names in the legend of the graphic above are
7826 instantiated with the types in the following table.
7827 </para>
7828
7829
7830 <informaltable frame="all">
7831
7832 <tgroup cols="3" align="left" colsep="1" rowsep="1">
7833 <colspec colname="c1"/>
7834 <colspec colname="c2"/>
7835 <colspec colname="c3"/>
7836 <thead>
7837 <row>
7838 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
7839 <entry><emphasis>Parameter</emphasis></entry>
7840 <entry><emphasis>Details</emphasis></entry>
7841 </row>
7842 </thead>
7843
7844 <tbody>
7845
7846 <!-- native 01 -->
7847 <row>
7848 <?dbhtml bgcolor="#B0B0B0" ?>
7849 <entry namest="c1" nameend="c3">
7850 n_pq_vector
7851 </entry>
7852 </row>
7853
7854 <row>
7855 <entry>
7856 <classname>std::priority_queue</classname>
7857 </entry>
7858 <entry>
7859 <classname>Sequence</classname>
7860 </entry>
7861 <entry>
7862 <classname>std::vector</classname>
7863 </entry>
7864 </row>
7865
7866 <!-- native 02 -->
7867 <row>
7868 <?dbhtml bgcolor="#B0B0B0" ?>
7869 <entry namest="c1" nameend="c3">
7870 n_pq_deque
7871 </entry>
7872 </row>
7873
7874 <row>
7875 <entry>
7876 <classname>std::priority_queue</classname>
7877 </entry>
7878 <entry>
7879 <classname>Sequence</classname>
7880 </entry>
7881 <entry>
7882 <classname>std::deque</classname>
7883 </entry>
7884
7885 </row>
7886
7887 <!-- priority_queue 01 -->
7888 <row>
7889 <?dbhtml bgcolor="#B0B0B0" ?>
7890 <entry namest="c1" nameend="c3">
7891 binary_heap
7892 </entry>
7893 </row>
7894
7895 <row>
7896 <entry>
7897 <classname>priority_queue</classname>
7898 </entry>
7899 <entry>
7900 <classname>Tag</classname>
7901 </entry>
7902 <entry>
7903 <classname>binary_heap_tag</classname>
7904 </entry>
7905 </row>
7906
7907 <!-- priority_queue 02 -->
7908 <row>
7909 <?dbhtml bgcolor="#B0B0B0" ?>
7910 <entry namest="c1" nameend="c3">
7911 binomial_heap
7912 </entry>
7913 </row>
7914
7915 <row>
7916 <entry>
7917 <classname>priority_queue</classname>
7918 </entry>
7919 <entry>
7920 <classname>Tag</classname>
7921 </entry>
7922 <entry>
7923 <classname>binomial_heap_tag</classname>
7924 </entry>
7925 </row>
7926
7927 <!-- priority_queue 03 -->
7928 <row>
7929 <?dbhtml bgcolor="#B0B0B0" ?>
7930 <entry namest="c1" nameend="c3">
7931 rc_binomial_heap
7932 </entry>
7933 </row>
7934
7935 <row>
7936 <entry>
7937 <classname>priority_queue</classname>
7938 </entry>
7939 <entry>
7940 <classname>Tag</classname>
7941 </entry>
7942 <entry>
7943 <classname>rc_binomial_heap_tag</classname>
7944 </entry>
7945 </row>
7946
7947 <!-- priority_queue 04 -->
7948 <row>
7949 <?dbhtml bgcolor="#B0B0B0" ?>
7950 <entry namest="c1" nameend="c3">
7951 thin_heap
7952 </entry>
7953 </row>
7954
7955 <row>
7956 <entry>
7957 <classname>priority_queue</classname>
7958 </entry>
7959 <entry>
7960 <classname>Tag</classname>
7961 </entry>
7962 <entry>
7963 <classname>thin_heap_tag</classname>
7964 </entry>
7965 </row>
7966
7967 <!-- priority_queue 05 -->
7968 <row>
7969 <?dbhtml bgcolor="#B0B0B0" ?>
7970 <entry namest="c1" nameend="c3">
7971 pairing_heap
7972 </entry>
7973 </row>
7974
7975 <row>
7976 <entry>
7977 <classname>priority_queue</classname>
7978 </entry>
7979 <entry>
7980 <classname>Tag</classname>
7981 </entry>
7982 <entry>
7983 <classname>pairing_heap_tag</classname>
7984 </entry>
7985 </row>
7986
7987 </tbody>
7988 </tgroup>
7989 </informaltable>
7990
7991
7992
7993 </section>
7994
7995 <section xml:id="priority_queue.int_push_pop.observations">
7996 <info><title>
7997 Observations
7998 </title></info>
7999
8000 <para>Binary heaps are the most suited for sequences of
8001 <function>push</function> and <function>pop</function> operations of primitive types
8002 (e.g. <type>int</type>s). This is explained in
8003 Priority
8004 Queue Random Int <function>push</function> Timing Test. (See Priority Queue
8005 Text <function>push</function> Timing Test for the case of primitive
8006 types.)</para>
8007
8008 <para>At first glance it seems that the standard's vector-based
8009 priority queue is approximately on par with this
8010 library's corresponding priority queue. There are two
8011 differences however:</para>
8012 <orderedlist>
8013 <listitem><para>The standard's priority queue does not downsize the underlying
8014 vector (or deque) as the priority queue becomes smaller
8015 (see Priority Queue
8016 Text <function>pop</function> Memory Use Test). It is therefore
8017 gaining some speed at the expense of space.</para></listitem>
8018 <listitem><para>From Priority Queue Random
8019 Integer <function>push</function> and <function>pop</function>
8020 Timing Test, it seems that the standard's priority queue is
8021 slower in terms of <function>push</function> operations. Since
8022 the number of
8023 <function>pop</function> operations is at most that of <function>push</function>
8024 operations, the test here is the "best" for the standard's
8025 priority queue.</para></listitem>
8026 </orderedlist>
8027
8028
8029 </section>
8030 </section>
8031
8032
8033 <!-- 05 <a href="priority_queue_text_pop_mem_usage_test"> -->
8034 <section xml:id="performance.priority_queue.text_pop">
8035 <info><title>
8036 Text <function>pop</function> Memory Use
8037 </title></info>
8038 <para></para>
8039
8040 <section xml:id="priority_queue.text_pop.info">
8041 <info><title>
8042 Description
8043 </title></info>
8044
8045
8046 <para>This test inserts a number of values with keys from an
8047 arbitrary text ([ wickland96thirty ]) into
8048 a container, then pops them until only one is left in the
8049 container. It measures the memory use as a function of the
8050 number of values pushed to the container.</para>
8051 <para>
8052 It uses the test file:
8053 <filename>
8054 performance/ext/pb_ds/priority_queue_text_pop_mem_usage.cc
8055 </filename>
8056 </para>
8057
8058 <para>The test checks the effect of different underlying data
8059 structures.
8060 </para>
8061
8062 </section>
8063
8064 <section xml:id="priority_queue.text_pop.results">
8065 <info><title>
8066 Results
8067 </title></info>
8068
8069 <para>The graphic immediately below shows the results for the
8070 native priority_queue type instantiated with different underlying
8071 container types versus several different versions of library's
8072 priority_queues.
8073 </para>
8074
8075 <!-- results graphic -->
8076 <informalfigure>
8077 <mediaobject>
8078 <imageobject>
8079 <imagedata align="center" format="PDF" scale="75"
8080 fileref="../images/pbds_priority_queue_text_pop_mem_usage_test_local.pdf"/>
8081 </imageobject>
8082 <imageobject>
8083 <imagedata align="center" format="PNG" scale="100"
8084 fileref="../images/pbds_priority_queue_text_pop_mem_usage_test_local.png"/>
8085 </imageobject>
8086 </mediaobject>
8087 </informalfigure>
8088
8089 <para>
8090 The abbreviated names in the legend of the graphic above are
8091 instantiated with the types in the following table.
8092 </para>
8093
8094
8095 <informaltable frame="all">
8096
8097 <tgroup cols="3" align="left" colsep="1" rowsep="1">
8098 <colspec colname="c1"/>
8099 <colspec colname="c2"/>
8100 <colspec colname="c3"/>
8101 <thead>
8102 <row>
8103 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
8104 <entry><emphasis>Parameter</emphasis></entry>
8105 <entry><emphasis>Details</emphasis></entry>
8106 </row>
8107 </thead>
8108
8109 <tbody>
8110
8111 <!-- native 01 -->
8112 <row>
8113 <?dbhtml bgcolor="#B0B0B0" ?>
8114 <entry namest="c1" nameend="c3">
8115 n_pq_vector
8116 </entry>
8117 </row>
8118
8119 <row>
8120 <entry>
8121 <classname>std::priority_queue</classname>
8122 </entry>
8123 <entry>
8124 <classname>Sequence</classname>
8125 </entry>
8126 <entry>
8127 <classname>std::vector</classname>
8128 </entry>
8129 </row>
8130
8131 <!-- native 02 -->
8132 <row>
8133 <?dbhtml bgcolor="#B0B0B0" ?>
8134 <entry namest="c1" nameend="c3">
8135 n_pq_deque
8136 </entry>
8137 </row>
8138
8139 <row>
8140 <entry>
8141 <classname>std::priority_queue</classname>
8142 </entry>
8143 <entry>
8144 <classname>Sequence</classname>
8145 </entry>
8146 <entry>
8147 <classname>std::deque</classname>
8148 </entry>
8149
8150 </row>
8151
8152 <!-- priority_queue 01 -->
8153 <row>
8154 <?dbhtml bgcolor="#B0B0B0" ?>
8155 <entry namest="c1" nameend="c3">
8156 binary_heap
8157 </entry>
8158 </row>
8159
8160 <row>
8161 <entry>
8162 <classname>priority_queue</classname>
8163 </entry>
8164 <entry>
8165 <classname>Tag</classname>
8166 </entry>
8167 <entry>
8168 <classname>binary_heap_tag</classname>
8169 </entry>
8170 </row>
8171
8172 <!-- priority_queue 02 -->
8173 <row>
8174 <?dbhtml bgcolor="#B0B0B0" ?>
8175 <entry namest="c1" nameend="c3">
8176 binomial_heap
8177 </entry>
8178 </row>
8179
8180 <row>
8181 <entry>
8182 <classname>priority_queue</classname>
8183 </entry>
8184 <entry>
8185 <classname>Tag</classname>
8186 </entry>
8187 <entry>
8188 <classname>binomial_heap_tag</classname>
8189 </entry>
8190 </row>
8191
8192 <!-- priority_queue 03 -->
8193 <row>
8194 <?dbhtml bgcolor="#B0B0B0" ?>
8195 <entry namest="c1" nameend="c3">
8196 rc_binomial_heap
8197 </entry>
8198 </row>
8199
8200 <row>
8201 <entry>
8202 <classname>priority_queue</classname>
8203 </entry>
8204 <entry>
8205 <classname>Tag</classname>
8206 </entry>
8207 <entry>
8208 <classname>rc_binomial_heap_tag</classname>
8209 </entry>
8210 </row>
8211
8212 <!-- priority_queue 04 -->
8213 <row>
8214 <?dbhtml bgcolor="#B0B0B0" ?>
8215 <entry namest="c1" nameend="c3">
8216 thin_heap
8217 </entry>
8218 </row>
8219
8220 <row>
8221 <entry>
8222 <classname>priority_queue</classname>
8223 </entry>
8224 <entry>
8225 <classname>Tag</classname>
8226 </entry>
8227 <entry>
8228 <classname>thin_heap_tag</classname>
8229 </entry>
8230 </row>
8231
8232 <!-- priority_queue 05 -->
8233 <row>
8234 <?dbhtml bgcolor="#B0B0B0" ?>
8235 <entry namest="c1" nameend="c3">
8236 pairing_heap
8237 </entry>
8238 </row>
8239
8240 <row>
8241 <entry>
8242 <classname>priority_queue</classname>
8243 </entry>
8244 <entry>
8245 <classname>Tag</classname>
8246 </entry>
8247 <entry>
8248 <classname>pairing_heap_tag</classname>
8249 </entry>
8250 </row>
8251
8252 </tbody>
8253 </tgroup>
8254 </informaltable>
8255
8256
8257
8258 </section>
8259
8260 <section xml:id="priority_queue.text_pop.observations">
8261 <info><title>
8262 Observations
8263 </title></info>
8264
8265
8266 <para>The priority queue implementations (excluding the standard's) use
8267 memory proportionally to the number of values they hold:
8268 node-based implementations (e.g., a pairing heap) do so
8269 naturally; this library's binary heap de-allocates memory when
8270 a certain lower threshold is exceeded.</para>
8271
8272 <para>Note from Priority Queue Text <function>push</function>
8273 and <function>pop</function> Timing Test and Priority Queue
8274 Random Integer <function>push</function>
8275 and <function>pop</function> Timing Test that this does not
8276 impede performance compared to the standard's priority
8277 queues.</para>
8278 <para>See Hash-Based Erase
8279 Memory Use Test for a similar phenomenon regarding priority
8280 queues.</para>
8281 </section>
8282 </section>
8283
8284 <!-- 06 <a href="priority_queue_text_join_timing_test"> -->
8285 <section xml:id="performance.priority_queue.text_join">
8286 <info><title>
8287 Text <function>join</function>
8288 </title></info>
8289 <para></para>
8290
8291 <section xml:id="priority_queue.text_join.info">
8292 <info><title>
8293 Description
8294 </title></info>
8295
8296 <para>This test inserts a number of values with keys from an
8297 arbitrary text ([ wickland96thirty ]) into
8298 two containers, then merges the containers. It uses
8299 <function>join</function> for this library's priority queues; for
8300 the standard's priority queues, it successively pops values from
8301 one container and pushes them into the other. The test measures
8302 the average time as a function of the number of values.</para>
8303 <para>
8304 It uses the test file:
8305 <filename>
8306 performance/ext/pb_ds/priority_queue_text_join_timing.cc
8307 </filename>
8308 </para>
8309
8310 <para>The test checks the effect of different underlying data
8311 structures.
8312 </para>
8313
8314 </section>
8315
8316 <section xml:id="priority_queue.text_join.results">
8317 <info><title>
8318 Results
8319 </title></info>
8320
8321 <para>The graphic immediately below shows the results for the
8322 native priority_queue type instantiated with different underlying
8323 container types versus several different versions of library's
8324 priority_queues.
8325 </para>
8326
8327 <!-- results graphic -->
8328 <informalfigure>
8329 <mediaobject>
8330 <imageobject>
8331 <imagedata align="center" format="PDF" scale="75"
8332 fileref="../images/pbds_priority_queue_text_join_timing_test_local.pdf"/>
8333 </imageobject>
8334 <imageobject>
8335 <imagedata align="center" format="PNG" scale="100"
8336 fileref="../images/pbds_priority_queue_text_join_timing_test_local.png"/>
8337 </imageobject>
8338 </mediaobject>
8339 </informalfigure>
8340
8341 <para>
8342 The abbreviated names in the legend of the graphic above are
8343 instantiated with the types in the following table.
8344 </para>
8345
8346
8347 <informaltable frame="all">
8348
8349 <tgroup cols="3" align="left" colsep="1" rowsep="1">
8350 <colspec colname="c1"/>
8351 <colspec colname="c2"/>
8352 <colspec colname="c3"/>
8353 <thead>
8354 <row>
8355 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
8356 <entry><emphasis>Parameter</emphasis></entry>
8357 <entry><emphasis>Details</emphasis></entry>
8358 </row>
8359 </thead>
8360
8361 <tbody>
8362
8363 <!-- native 01 -->
8364 <row>
8365 <?dbhtml bgcolor="#B0B0B0" ?>
8366 <entry namest="c1" nameend="c3">
8367 n_pq_vector
8368 </entry>
8369 </row>
8370
8371 <row>
8372 <entry>
8373 <classname>std::priority_queue</classname>
8374 </entry>
8375 <entry>
8376 <classname>Sequence</classname>
8377 </entry>
8378 <entry>
8379 <classname>std::vector</classname>
8380 </entry>
8381 </row>
8382
8383 <!-- native 02 -->
8384 <row>
8385 <?dbhtml bgcolor="#B0B0B0" ?>
8386 <entry namest="c1" nameend="c3">
8387 n_pq_deque
8388 </entry>
8389 </row>
8390
8391 <row>
8392 <entry>
8393 <classname>std::priority_queue</classname>
8394 </entry>
8395 <entry>
8396 <classname>Sequence</classname>
8397 </entry>
8398 <entry>
8399 <classname>std::deque</classname>
8400 </entry>
8401
8402 </row>
8403
8404 <!-- priority_queue 01 -->
8405 <row>
8406 <?dbhtml bgcolor="#B0B0B0" ?>
8407 <entry namest="c1" nameend="c3">
8408 binary_heap
8409 </entry>
8410 </row>
8411
8412 <row>
8413 <entry>
8414 <classname>priority_queue</classname>
8415 </entry>
8416 <entry>
8417 <classname>Tag</classname>
8418 </entry>
8419 <entry>
8420 <classname>binary_heap_tag</classname>
8421 </entry>
8422 </row>
8423
8424 <!-- priority_queue 02 -->
8425 <row>
8426 <?dbhtml bgcolor="#B0B0B0" ?>
8427 <entry namest="c1" nameend="c3">
8428 binomial_heap
8429 </entry>
8430 </row>
8431
8432 <row>
8433 <entry>
8434 <classname>priority_queue</classname>
8435 </entry>
8436 <entry>
8437 <classname>Tag</classname>
8438 </entry>
8439 <entry>
8440 <classname>binomial_heap_tag</classname>
8441 </entry>
8442 </row>
8443
8444 <!-- priority_queue 03 -->
8445 <row>
8446 <?dbhtml bgcolor="#B0B0B0" ?>
8447 <entry namest="c1" nameend="c3">
8448 rc_binomial_heap
8449 </entry>
8450 </row>
8451
8452 <row>
8453 <entry>
8454 <classname>priority_queue</classname>
8455 </entry>
8456 <entry>
8457 <classname>Tag</classname>
8458 </entry>
8459 <entry>
8460 <classname>rc_binomial_heap_tag</classname>
8461 </entry>
8462 </row>
8463
8464 <!-- priority_queue 04 -->
8465 <row>
8466 <?dbhtml bgcolor="#B0B0B0" ?>
8467 <entry namest="c1" nameend="c3">
8468 thin_heap
8469 </entry>
8470 </row>
8471
8472 <row>
8473 <entry>
8474 <classname>priority_queue</classname>
8475 </entry>
8476 <entry>
8477 <classname>Tag</classname>
8478 </entry>
8479 <entry>
8480 <classname>thin_heap_tag</classname>
8481 </entry>
8482 </row>
8483
8484 <!-- priority_queue 05 -->
8485 <row>
8486 <?dbhtml bgcolor="#B0B0B0" ?>
8487 <entry namest="c1" nameend="c3">
8488 pairing_heap
8489 </entry>
8490 </row>
8491
8492 <row>
8493 <entry>
8494 <classname>priority_queue</classname>
8495 </entry>
8496 <entry>
8497 <classname>Tag</classname>
8498 </entry>
8499 <entry>
8500 <classname>pairing_heap_tag</classname>
8501 </entry>
8502 </row>
8503
8504 </tbody>
8505 </tgroup>
8506 </informaltable>
8507
8508
8509
8510 </section>
8511
8512 <section xml:id="priority_queue.text_join.observations">
8513 <info><title>
8514 Observations
8515 </title></info>
8516
8517 <para>In this test the node-based heaps perform <function>join</function> in
8518 either logarithmic or constant time. The binary heap requires
8519 linear time, since the well-known heapify algorithm [clrs2001] is linear.</para>
8520 <para>It would be possible to apply the heapify algorithm to the
8521 standard containers, if they would support iteration (which they
8522 don't). Barring iterators, it is still somehow possible to perform
8523 linear-time merge on a <classname>std::vector</classname>-based
8524 standard priority queue, using <function>top()</function>
8525 and <function>size()</function> (since they are enough to expose
8526 the underlying array), but this is impossible for
8527 a <classname>std::deque</classname>-based standard priority queue.
8528 Without heapify, the cost is super-linear.</para>
8529 </section>
8530 </section>
8531
8532
8533 <!-- 07 <a href="priority_queue_text_push_timing_test"> -->
8534 <section xml:id="performance.priority_queue.text_modify_up">
8535 <info><title>
8536 Text <function>modify</function> Up
8537 </title></info>
8538 <para></para>
8539
8540 <section xml:id="priority_queue.text_modify_up.info">
8541 <info><title>
8542 Description
8543 </title></info>
8544
8545 <para>This test inserts a number of values with keys from an
8546 arbitrary text ([ wickland96thirty ]) into
8547 into a container then modifies each one "up" (i.e., it
8548 makes it larger). It uses <function>modify</function> for this library's
8549 priority queues; for the standard's priority queues, it pops values
8550 from a container until it reaches the value that should be
8551 modified, then pushes values back in. It measures the average
8552 time for <function>modify</function> as a function of the number of
8553 values.</para>
8554
8555 <para>
8556 It uses the test file:
8557 <filename>
8558 performance/ext/pb_ds/priority_queue_text_modify_up_timing.cc
8559 </filename>
8560 </para>
8561
8562 <para>The test checks the effect of different underlying data
8563 structures for graph algorithms settings. Note that making an
8564 arbitrary value larger (in the sense of the priority queue's
8565 comparison functor) corresponds to decrease-key in standard graph
8566 algorithms [clrs2001].
8567 </para>
8568
8569 </section>
8570
8571 <section xml:id="priority_queue.text_modify_up.results">
8572 <info><title>
8573 Results
8574 </title></info>
8575
8576 <para>The two graphics below show the results for the native
8577 priority_queues and this library's priority_queues.
8578 </para>
8579
8580 <para>The graphic immediately below shows the results for the
8581 native priority_queue type instantiated with different underlying
8582 container types versus several different versions of library's
8583 priority_queues.
8584 </para>
8585
8586 <!-- results graphic -->
8587 <informalfigure>
8588 <mediaobject>
8589 <imageobject>
8590 <imagedata align="center" format="PDF" scale="75"
8591 fileref="../images/pbds_priority_queue_text_modify_up_timing_test_local.pdf"/>
8592 </imageobject>
8593 <imageobject>
8594 <imagedata align="center" format="PNG" scale="100"
8595 fileref="../images/pbds_priority_queue_text_modify_up_timing_test_local.png"/>
8596 </imageobject>
8597 </mediaobject>
8598 </informalfigure>
8599
8600 <para>
8601 The abbreviated names in the legend of the graphic above are
8602 instantiated with the types in the following table.
8603 </para>
8604
8605
8606 <informaltable frame="all">
8607
8608 <tgroup cols="3" align="left" colsep="1" rowsep="1">
8609 <colspec colname="c1"/>
8610 <colspec colname="c2"/>
8611 <colspec colname="c3"/>
8612 <thead>
8613 <row>
8614 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
8615 <entry><emphasis>Parameter</emphasis></entry>
8616 <entry><emphasis>Details</emphasis></entry>
8617 </row>
8618 </thead>
8619
8620 <tbody>
8621
8622 <!-- native 01 -->
8623 <row>
8624 <?dbhtml bgcolor="#B0B0B0" ?>
8625 <entry namest="c1" nameend="c3">
8626 n_pq_vector
8627 </entry>
8628 </row>
8629
8630 <row>
8631 <entry>
8632 <classname>std::priority_queue</classname>
8633 </entry>
8634 <entry>
8635 <classname>Sequence</classname>
8636 </entry>
8637 <entry>
8638 <classname>std::vector</classname>
8639 </entry>
8640 </row>
8641
8642 <!-- native 02 -->
8643 <row>
8644 <?dbhtml bgcolor="#B0B0B0" ?>
8645 <entry namest="c1" nameend="c3">
8646 n_pq_deque
8647 </entry>
8648 </row>
8649
8650 <row>
8651 <entry>
8652 <classname>std::priority_queue</classname>
8653 </entry>
8654 <entry>
8655 <classname>Sequence</classname>
8656 </entry>
8657 <entry>
8658 <classname>std::deque</classname>
8659 </entry>
8660 </row>
8661
8662 <!-- priority_queue 01 -->
8663 <row>
8664 <?dbhtml bgcolor="#B0B0B0" ?>
8665 <entry namest="c1" nameend="c3">
8666 binary_heap
8667 </entry>
8668 </row>
8669
8670 <row>
8671 <entry>
8672 <classname>priority_queue</classname>
8673 </entry>
8674 <entry>
8675 <classname>Tag</classname>
8676 </entry>
8677 <entry>
8678 <classname>binary_heap_tag</classname>
8679 </entry>
8680 </row>
8681
8682 <!-- priority_queue 02 -->
8683 <row>
8684 <?dbhtml bgcolor="#B0B0B0" ?>
8685 <entry namest="c1" nameend="c3">
8686 binomial_heap
8687 </entry>
8688 </row>
8689
8690 <row>
8691 <entry>
8692 <classname>priority_queue</classname>
8693 </entry>
8694 <entry>
8695 <classname>Tag</classname>
8696 </entry>
8697 <entry>
8698 <classname>binomial_heap_tag</classname>
8699 </entry>
8700 </row>
8701
8702 <!-- priority_queue 03 -->
8703 <row>
8704 <?dbhtml bgcolor="#B0B0B0" ?>
8705 <entry namest="c1" nameend="c3">
8706 rc_binomial_heap
8707 </entry>
8708 </row>
8709
8710 <row>
8711 <entry>
8712 <classname>priority_queue</classname>
8713 </entry>
8714 <entry>
8715 <classname>Tag</classname>
8716 </entry>
8717 <entry>
8718 <classname>rc_binomial_heap_tag</classname>
8719 </entry>
8720 </row>
8721
8722 <!-- priority_queue 04 -->
8723 <row>
8724 <?dbhtml bgcolor="#B0B0B0" ?>
8725 <entry namest="c1" nameend="c3">
8726 thin_heap
8727 </entry>
8728 </row>
8729
8730 <row>
8731 <entry>
8732 <classname>priority_queue</classname>
8733 </entry>
8734 <entry>
8735 <classname>Tag</classname>
8736 </entry>
8737 <entry>
8738 <classname>thin_heap_tag</classname>
8739 </entry>
8740 </row>
8741
8742
8743 <!-- priority_queue 05 -->
8744 <row>
8745 <?dbhtml bgcolor="#B0B0B0" ?>
8746 <entry namest="c1" nameend="c3">
8747 pairing_heap
8748 </entry>
8749 </row>
8750
8751 <row>
8752 <entry>
8753 <classname>priority_queue</classname>
8754 </entry>
8755 <entry>
8756 <classname>Tag</classname>
8757 </entry>
8758 <entry>
8759 <classname>pairing_heap_tag</classname>
8760 </entry>
8761 </row>
8762
8763 </tbody>
8764 </tgroup>
8765 </informaltable>
8766
8767
8768
8769 <para>The graphic below shows the results for the
8770 native priority queues and this library's pairing and thin heap
8771 priority_queue data structures.
8772 </para>
8773
8774 <!-- results graphic -->
8775 <informalfigure>
8776 <mediaobject>
8777 <imageobject>
8778 <imagedata align="center" format="PDF" scale="75"
8779 fileref="../images/pbds_priority_queue_text_modify_up_timing_test_pairing_thin_local.pdf"/>
8780 </imageobject>
8781 <imageobject>
8782 <imagedata align="center" format="PNG" scale="100"
8783 fileref="../images/pbds_priority_queue_text_modify_up_timing_test_pairing_thin_local.png"/>
8784 </imageobject>
8785 </mediaobject>
8786 </informalfigure>
8787
8788 <para>
8789 The abbreviated names in the legend of the graphic above are
8790 instantiated with the types in the following table.
8791 </para>
8792
8793
8794 <informaltable frame="all">
8795
8796 <tgroup cols="3" align="left" colsep="1" rowsep="1">
8797 <colspec colname="c1"/>
8798 <colspec colname="c2"/>
8799 <colspec colname="c3"/>
8800 <thead>
8801 <row>
8802 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
8803 <entry><emphasis>Parameter</emphasis></entry>
8804 <entry><emphasis>Details</emphasis></entry>
8805 </row>
8806 </thead>
8807
8808 <tbody>
8809
8810 <!-- priority_queue 01 -->
8811 <row>
8812 <?dbhtml bgcolor="#B0B0B0" ?>
8813 <entry namest="c1" nameend="c3">
8814 thin_heap
8815 </entry>
8816 </row>
8817
8818 <row>
8819 <entry>
8820 <classname>priority_queue</classname>
8821 </entry>
8822 <entry>
8823 <classname>Tag</classname>
8824 </entry>
8825 <entry>
8826 <classname>thin_heap_tag</classname>
8827 </entry>
8828 </row>
8829
8830
8831 <!-- priority_queue 02 -->
8832 <row>
8833 <?dbhtml bgcolor="#B0B0B0" ?>
8834 <entry namest="c1" nameend="c3">
8835 pairing_heap
8836 </entry>
8837 </row>
8838
8839 <row>
8840 <entry>
8841 <classname>priority_queue</classname>
8842 </entry>
8843 <entry>
8844 <classname>Tag</classname>
8845 </entry>
8846 <entry>
8847 <classname>pairing_heap_tag</classname>
8848 </entry>
8849 </row>
8850
8851 </tbody>
8852 </tgroup>
8853 </informaltable>
8854
8855
8856 </section>
8857
8858 <section xml:id="priority_queue.text_modify_up.observations">
8859 <info><title>
8860 Observations
8861 </title></info>
8862
8863 <para>As noted above, increasing an arbitrary value (in the sense of
8864 the priority queue's comparison functor) is very common in
8865 graph-related algorithms. In this case, a thin heap
8866 (<classname>priority_queue</classname> with
8867 <classname>Tag</classname> = <classname>thin_heap_tag</classname>)
8868 outperforms a pairing heap (<classname>priority_queue</classname> with
8869 <classname>Tag</classname> = <classname>pairing_heap_tag</classname>).
8870 Conversely, Priority Queue Text
8871 <function>push</function> Timing Test, Priority Queue
8872 Text <function>push</function> and <function>pop</function> Timing Test, Priority
8873 Queue Random Integer <function>push</function> Timing Test, and
8874 Priority
8875 Queue Random Integer <function>push</function> and <function>pop</function> Timing
8876 Test show that the situation is reversed for other
8877 operations. It is not clear when to prefer one of these two
8878 different types.</para>
8879
8880 <para>In this test this library's binary heaps
8881 effectively perform modify in linear time. As explained in
8882 Priority Queue Design::Traits, given a valid point-type iterator,
8883 a binary heap can perform
8884 <function>modify</function> logarithmically. The problem is that binary
8885 heaps invalidate their find iterators with each modifying
8886 operation, and so the only way to obtain a valid point-type
8887 iterator is to iterate using a range-type iterator until
8888 finding the appropriate value, then use the range-type iterator
8889 for the <function>modify</function> operation.</para>
8890 <para>The explanation for the standard's priority queues' performance
8891 is similar to that in Priority Queue Text
8892 <function>join</function> Timing Test.</para>
8893
8894
8895 </section>
8896 </section>
8897
8898 <!-- 08 <a href="priority_queue_text_modify_down_timing_test"> -->
8899
8900 <section xml:id="performance.priority_queue.text_modify_down">
8901 <info><title>
8902 Text <function>modify</function> Down
8903 </title></info>
8904 <para></para>
8905
8906 <section xml:id="priority_queue.text_modify_down.info">
8907 <info><title>
8908 Description
8909 </title></info>
8910
8911 <para>This test inserts a number of values with keys from an
8912 arbitrary text ([ wickland96thirty ]) into
8913 into a container then modifies each one "down" (i.e., it
8914 makes it smaller). It uses <function>modify</function> for this library's
8915 priority queues; for the standard's priority queues, it pops values
8916 from a container until it reaches the value that should be
8917 modified, then pushes values back in. It measures the average
8918 time for <function>modify</function> as a function of the number of
8919 values.</para>
8920
8921 <para>
8922 It uses the test file:
8923 <filename>
8924 performance/ext/pb_ds/priority_queue_text_modify_down_timing.cc
8925 </filename>
8926 </para>
8927
8928 <para>The main purpose of this test is to contrast Priority Queue
8929 Text <classname>modify</classname> Up Timing Test.</para>
8930
8931 </section>
8932
8933 <section xml:id="priority_queue.text_modify_down.results">
8934 <info><title>
8935 Results
8936 </title></info>
8937
8938 <para>The two graphics below show the results for the native
8939 priority_queues and this library's priority_queues.
8940 </para>
8941
8942 <para>The graphic immediately below shows the results for the
8943 native priority_queue type instantiated with different underlying
8944 container types versus several different versions of library's
8945 priority_queues.
8946 </para>
8947
8948 <!-- results graphic -->
8949 <informalfigure>
8950 <mediaobject>
8951 <imageobject>
8952 <imagedata align="center" format="PDF" scale="75"
8953 fileref="../images/pbds_priority_queue_text_modify_down_timing_test_local.pdf"/>
8954 </imageobject>
8955 <imageobject>
8956 <imagedata align="center" format="PNG" scale="100"
8957 fileref="../images/pbds_priority_queue_text_modify_down_timing_test_local.png"/>
8958 </imageobject>
8959 </mediaobject>
8960 </informalfigure>
8961
8962 <para>
8963 The abbreviated names in the legend of the graphic above are
8964 instantiated with the types in the following table.
8965 </para>
8966
8967
8968 <informaltable frame="all">
8969
8970 <tgroup cols="3" align="left" colsep="1" rowsep="1">
8971 <colspec colname="c1"/>
8972 <colspec colname="c2"/>
8973 <colspec colname="c3"/>
8974 <thead>
8975 <row>
8976 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
8977 <entry><emphasis>Parameter</emphasis></entry>
8978 <entry><emphasis>Details</emphasis></entry>
8979 </row>
8980 </thead>
8981
8982 <tbody>
8983
8984 <!-- native 01 -->
8985 <row>
8986 <?dbhtml bgcolor="#B0B0B0" ?>
8987 <entry namest="c1" nameend="c3">
8988 n_pq_vector
8989 </entry>
8990 </row>
8991
8992 <row>
8993 <entry>
8994 <classname>std::priority_queue</classname>
8995 </entry>
8996 <entry>
8997 <classname>Sequence</classname>
8998 </entry>
8999 <entry>
9000 <classname>std::vector</classname>
9001 </entry>
9002 </row>
9003
9004 <!-- native 02 -->
9005 <row>
9006 <?dbhtml bgcolor="#B0B0B0" ?>
9007 <entry namest="c1" nameend="c3">
9008 n_pq_deque
9009 </entry>
9010 </row>
9011
9012 <row>
9013 <entry>
9014 <classname>std::priority_queue</classname>
9015 </entry>
9016 <entry>
9017 <classname>Sequence</classname>
9018 </entry>
9019 <entry>
9020 <classname>std::deque</classname>
9021 </entry>
9022 </row>
9023
9024 <!-- priority_queue 01 -->
9025 <row>
9026 <?dbhtml bgcolor="#B0B0B0" ?>
9027 <entry namest="c1" nameend="c3">
9028 binary_heap
9029 </entry>
9030 </row>
9031
9032 <row>
9033 <entry>
9034 <classname>priority_queue</classname>
9035 </entry>
9036 <entry>
9037 <classname>Tag</classname>
9038 </entry>
9039 <entry>
9040 <classname>binary_heap_tag</classname>
9041 </entry>
9042 </row>
9043
9044 <!-- priority_queue 02 -->
9045 <row>
9046 <?dbhtml bgcolor="#B0B0B0" ?>
9047 <entry namest="c1" nameend="c3">
9048 binomial_heap
9049 </entry>
9050 </row>
9051
9052 <row>
9053 <entry>
9054 <classname>priority_queue</classname>
9055 </entry>
9056 <entry>
9057 <classname>Tag</classname>
9058 </entry>
9059 <entry>
9060 <classname>binomial_heap_tag</classname>
9061 </entry>
9062 </row>
9063
9064 <!-- priority_queue 03 -->
9065 <row>
9066 <?dbhtml bgcolor="#B0B0B0" ?>
9067 <entry namest="c1" nameend="c3">
9068 rc_binomial_heap
9069 </entry>
9070 </row>
9071
9072 <row>
9073 <entry>
9074 <classname>priority_queue</classname>
9075 </entry>
9076 <entry>
9077 <classname>Tag</classname>
9078 </entry>
9079 <entry>
9080 <classname>rc_binomial_heap_tag</classname>
9081 </entry>
9082 </row>
9083
9084 <!-- priority_queue 04 -->
9085 <row>
9086 <?dbhtml bgcolor="#B0B0B0" ?>
9087 <entry namest="c1" nameend="c3">
9088 thin_heap
9089 </entry>
9090 </row>
9091
9092 <row>
9093 <entry>
9094 <classname>priority_queue</classname>
9095 </entry>
9096 <entry>
9097 <classname>Tag</classname>
9098 </entry>
9099 <entry>
9100 <classname>thin_heap_tag</classname>
9101 </entry>
9102 </row>
9103
9104
9105 <!-- priority_queue 05 -->
9106 <row>
9107 <?dbhtml bgcolor="#B0B0B0" ?>
9108 <entry namest="c1" nameend="c3">
9109 pairing_heap
9110 </entry>
9111 </row>
9112
9113 <row>
9114 <entry>
9115 <classname>priority_queue</classname>
9116 </entry>
9117 <entry>
9118 <classname>Tag</classname>
9119 </entry>
9120 <entry>
9121 <classname>pairing_heap_tag</classname>
9122 </entry>
9123 </row>
9124
9125 </tbody>
9126 </tgroup>
9127 </informaltable>
9128
9129
9130
9131 <para>The graphic below shows the results for the
9132 native priority queues and this library's pairing and thin heap
9133 priority_queue data structures.
9134 </para>
9135
9136 <!-- results graphic -->
9137 <informalfigure>
9138 <mediaobject>
9139 <imageobject>
9140 <imagedata align="center" format="PDF" scale="75"
9141 fileref="../images/pbds_priority_queue_text_modify_down_timing_test_pairing_thin_local.pdf"/>
9142 </imageobject>
9143 <imageobject>
9144 <imagedata align="center" format="PNG" scale="100"
9145 fileref="../images/pbds_priority_queue_text_modify_down_timing_test_pairing_thin_local.png"/>
9146 </imageobject>
9147 </mediaobject>
9148 </informalfigure>
9149
9150 <para>
9151 The abbreviated names in the legend of the graphic above are
9152 instantiated with the types in the following table.
9153 </para>
9154
9155
9156 <informaltable frame="all">
9157
9158 <tgroup cols="3" align="left" colsep="1" rowsep="1">
9159 <colspec colname="c1"/>
9160 <colspec colname="c2"/>
9161 <colspec colname="c3"/>
9162 <thead>
9163 <row>
9164 <entry><emphasis>Name/Instantiating Type</emphasis></entry>
9165 <entry><emphasis>Parameter</emphasis></entry>
9166 <entry><emphasis>Details</emphasis></entry>
9167 </row>
9168 </thead>
9169
9170 <tbody>
9171
9172 <!-- priority_queue 01 -->
9173 <row>
9174 <?dbhtml bgcolor="#B0B0B0" ?>
9175 <entry namest="c1" nameend="c3">
9176 thin_heap
9177 </entry>
9178 </row>
9179
9180 <row>
9181 <entry>
9182 <classname>priority_queue</classname>
9183 </entry>
9184 <entry>
9185 <classname>Tag</classname>
9186 </entry>
9187 <entry>
9188 <classname>thin_heap_tag</classname>
9189 </entry>
9190 </row>
9191
9192
9193 <!-- priority_queue 02 -->
9194 <row>
9195 <?dbhtml bgcolor="#B0B0B0" ?>
9196 <entry namest="c1" nameend="c3">
9197 pairing_heap
9198 </entry>
9199 </row>
9200
9201 <row>
9202 <entry>
9203 <classname>priority_queue</classname>
9204 </entry>
9205 <entry>
9206 <classname>Tag</classname>
9207 </entry>
9208 <entry>
9209 <classname>pairing_heap_tag</classname>
9210 </entry>
9211 </row>
9212
9213 </tbody>
9214 </tgroup>
9215 </informaltable>
9216
9217
9218 </section>
9219
9220 <section xml:id="priority_queue.text_modify_down.observations">
9221 <info><title>
9222 Observations
9223 </title></info>
9224
9225 <para>Most points in these results are similar to Priority Queue
9226 Text <function>modify</function> Up Timing Test.</para>
9227
9228 <para>It is interesting to note, however, that as opposed to that
9229 test, a thin heap (<classname>priority_queue</classname> with
9230 <classname>Tag</classname> = <classname>thin_heap_tag</classname>) is
9231 outperformed by a pairing heap (<classname>priority_queue</classname> with
9232 <classname>Tag</classname> = <classname>pairing_heap_tag</classname>).
9233 In this case, both heaps essentially perform an <function>erase</function>
9234 operation followed by a <function>push</function> operation. As the other
9235 tests show, a pairing heap is usually far more efficient than a
9236 thin heap, so this is not surprising.</para>
9237 <para>Most algorithms that involve priority queues increase values
9238 (in the sense of the priority queue's comparison functor), and
9239 so Priority Queue
9240 Text <classname>modify</classname> Up Timing Test - is more interesting
9241 than this test.</para>
9242 </section>
9243 </section>
9244
9245
9246 </section> <!-- priority_queue -->
9247
9248 <section xml:id="pbds.test.performance.observations">
9249 <info><title>Observations</title></info>
9250
9251 <section xml:id="observations.associative">
9252 <info><title>Associative</title></info>
9253
9254 <section xml:id="observations.associative.underlying">
9255 <info><title>
9256 Underlying Data-Structure Families
9257 </title></info>
9258
9259 <para>In general, hash-based containers have better timing performance
9260 than containers based on different underlying-data structures. The
9261 main reason to choose a tree-based or trie-based container is if a
9262 byproduct of the tree-like structure is required: either
9263 order-preservation, or the ability to utilize node invariants. If
9264 memory-use is the major factor, an ordered-vector tree gives
9265 optimal results (albeit with high modificiation costs), and a
9266 list-based container gives reasonable results.</para>
9267
9268 </section>
9269
9270 <section xml:id="observations.associative.hash">
9271 <info><title>
9272 Hash-Based Containers
9273 </title></info>
9274
9275 <para>Hash-based containers are typically either collision
9276 chaining or probing. Collision-chaining
9277 containers are more flexible internally, and so offer better
9278 timing performance. Probing containers, if used for simple
9279 value-types, manage memory more efficiently (they perform far
9280 fewer allocation-related calls). In general, therefore, a
9281 collision-chaining table should be used. A probing container,
9282 conversely, might be used efficiently for operations such as
9283 eliminating duplicates in a sequence, or counting the number of
9284 occurrences within a sequence. Probing containers might be more
9285 useful also in multithreaded applications where each thread
9286 manipulates a hash-based container: in the standard, allocators have
9287 class-wise semantics (see [meyers96more] - Item 10); a
9288 probing container might incur less contention in this case.</para>
9289 </section>
9290
9291 <section xml:id="observations.associative.hash_policies">
9292 <info><title>
9293 Hash Policies
9294 </title></info>
9295
9296 <para>In hash-based containers, the range-hashing scheme seems to
9297 affect performance more than other considerations. In most
9298 settings, a mask-based scheme works well (or can be made to
9299 work well). If the key-distribution can be estimated a-priori,
9300 a simple hash function can produce nearly uniform hash-value
9301 distribution. In many other cases (e.g., text hashing,
9302 floating-point hashing), the hash function is powerful enough
9303 to generate hash values with good uniformity properties
9304 [knuth98sorting];
9305 a modulo-based scheme, taking into account all bits of the hash
9306 value, appears to overlap the hash function in its effort.</para>
9307 <para>The range-hashing scheme determines many of the other
9308 policies. A mask-based scheme works
9309 well with an exponential-size policy; for
9310 probing-based containers, it goes well with a linear-probe
9311 function.</para>
9312 <para>An orthogonal consideration is the trigger policy. This
9313 presents difficult tradeoffs. E.g., different load
9314 factors in a load-check trigger policy yield a
9315 space/amortized-cost tradeoff.</para>
9316 </section>
9317
9318 <section xml:id="observations.associative.branch">
9319 <info><title>
9320 Branch-Based Containers
9321 </title></info>
9322 <para>In general, there are several families of tree-based
9323 underlying data structures: balanced node-based trees
9324 (e.g., red-black or AVL trees), high-probability
9325 balanced node-based trees (e.g., random treaps or
9326 skip-lists), competitive node-based trees (e.g., splay
9327 trees), vector-based "trees", and tries. (Additionally, there
9328 are disk-residing or network-residing trees, such as B-Trees
9329 and their numerous variants. An interface for this would have
9330 to deal with the execution model and ACID guarantees; this is
9331 out of the scope of this library.) Following are some
9332 observations on their application to different settings.</para>
9333
9334 <para>Of the balanced node-based trees, this library includes a
9335 red-black tree, as does standard (in
9336 practice). This type of tree is the "workhorse" of tree-based
9337 containers: it offers both reasonable modification and
9338 reasonable lookup time. Unfortunately, this data structure
9339 stores a huge amount of metadata. Each node must contain,
9340 besides a value, three pointers and a boolean. This type might
9341 be avoided if space is at a premium [austern00noset].</para>
9342 <para>High-probability balanced node-based trees suffer the
9343 drawbacks of deterministic balanced trees. Although they are
9344 fascinating data structures, preliminary tests with them showed
9345 their performance was worse than red-black trees. The library
9346 does not contain any such trees, therefore.</para>
9347 <para>Competitive node-based trees have two drawbacks. They are
9348 usually somewhat unbalanced, and they perform a large number of
9349 comparisons. Balanced trees perform one comparison per each
9350 node they encounter on a search path; a splay tree performs two
9351 comparisons. If the keys are complex objects, e.g.,
9352 <classname>std::string</classname>, this can increase the running time.
9353 Conversely, such trees do well when there is much locality of
9354 reference. It is difficult to determine in which case to prefer
9355 such trees over balanced trees. This library includes a splay
9356 tree.</para>
9357 <para>Ordered-vector trees use very little space
9358 [austern00noset].
9359 They do not have any other advantages (at least in this
9360 implementation).</para>
9361 <para>Large-fan-out PATRICIA tries have excellent lookup
9362 performance, but they do so through maintaining, for each node,
9363 a miniature "hash-table". Their space efficiency is low, and
9364 their modification performance is bad. These tries might be
9365 used for semi-static settings, where order preservation is
9366 important. Alternatively, red-black trees cross-referenced with
9367 hash tables can be used. [okasaki98mereable]
9368 discusses small-fan-out PATRICIA tries for integers, but the
9369 cited results seem to indicate that the amortized cost of
9370 maintaining such trees is higher than that of balanced trees.
9371 Moderate-fan-out trees might be useful for sequences where each
9372 element has a limited number of choices, e.g., DNA
9373 strings.</para>
9374 </section>
9375
9376 <section xml:id="observations.associative.mapping_semantics">
9377 <info><title>
9378 Mapping-Semantics
9379 </title></info>
9380 <para>Different mapping semantics were discussed in the introduction and design sections.Here
9381 the focus will be on the case where a keys can be composed into
9382 primary keys and secondary keys. (In the case where some keys
9383 are completely identical, it is trivial that one should use an
9384 associative container mapping values to size types.) In this
9385 case there are (at least) five possibilities:</para>
9386 <orderedlist>
9387 <listitem><para>Use an associative container that allows equivalent-key
9388 values (such as <classname>std::multimap</classname>)</para></listitem>
9389 <listitem><para>Use a unique-key value associative container that maps
9390 each primary key to some complex associative container of
9391 secondary keys, say a tree-based or hash-based container.
9392 </para></listitem>
9393 <listitem><para>Use a unique-key value associative container that maps
9394 each primary key to some simple associative container of
9395 secondary keys, say a list-based container.</para></listitem>
9396 <listitem><para>Use a unique-key value associative container that maps
9397 each primary key to some non-associative container
9398 (e.g., <classname>std::vector</classname>)</para></listitem>
9399 <listitem><para>Use a unique-key value associative container that takes
9400 into account both primary and secondary keys.</para></listitem>
9401 </orderedlist>
9402 <para>Stated simply: there is a simple answer for this. (Excluding
9403 option 1, which should be avoided in all cases).</para>
9404 <para>If the expected ratio of secondary keys to primary keys is
9405 small, then 3 and 4 seem reasonable. Both types of secondary
9406 containers are relatively lightweight (in terms of memory use
9407 and construction time), and so creating an entire container
9408 object for each primary key is not too expensive. Option 4
9409 might be preferable to option 3 if changing the secondary key
9410 of some primary key is frequent - one cannot modify an
9411 associative container's key, and the only possibility,
9412 therefore, is erasing the secondary key and inserting another
9413 one instead; a non-associative container, conversely, can
9414 support in-place modification. The actual cost of erasing a
9415 secondary key and inserting another one depends also on the
9416 allocator used for secondary associative-containers (The tests
9417 above used the standard allocator, but in practice one might
9418 choose to use, e.g., [boost_pool]). Option 2 is
9419 definitely an overkill in this case. Option 1 loses out either
9420 immediately (when there is one secondary key per primary key)
9421 or almost immediately after that. Option 5 has the same
9422 drawbacks as option 2, but it has the additional drawback that
9423 finding all values whose primary key is equivalent to some key,
9424 might be linear in the total number of values stored (for
9425 example, if using a hash-based container).</para>
9426 <para>If the expected ratio of secondary keys to primary keys is
9427 large, then the answer is more complicated. It depends on the
9428 distribution of secondary keys to primary keys, the
9429 distribution of accesses according to primary keys, and the
9430 types of operations most frequent.</para>
9431 <para>To be more precise, assume there are m primary keys,
9432 primary key i is mapped to n<subscript>i</subscript>
9433 secondary keys, and each primary key is mapped, on average, to
9434 n secondary keys (i.e.,
9435 E(n<subscript>i</subscript>) = n).</para>
9436 <para>Suppose one wants to find a specific pair of primary and
9437 secondary keys. Using 1 with a tree based container
9438 (<classname>std::multimap</classname>), the expected cost is
9439 E(Θ(log(m) + n<subscript>i</subscript>)) = Θ(log(m) +
9440 n); using 1 with a hash-based container
9441 (<classname>std::tr1::unordered_multimap</classname>), the expected cost is
9442 Θ(n). Using 2 with a primary hash-based container
9443 and secondary hash-based containers, the expected cost is
9444 O(1); using 2 with a primary tree-based container and
9445 secondary tree-based containers, the expected cost is (using
9446 the Jensen inequality [motwani95random])
9447 E(O(log(m) + log(n<subscript>i</subscript>)) = O(log(m)) +
9448 E(O(log(n<subscript>i</subscript>)) = O(log(m)) + O(log(n)),
9449 assuming that primary keys are accessed equiprobably. 3 and 4
9450 are similar to 1, but with lower constants. Using 5 with a
9451 hash-based container, the expected cost is O(1); using 5
9452 with a tree based container, the cost is
9453 E(Θ(log(mn))) = Θ(log(m) +
9454 log(n)).</para>
9455 <para>Suppose one needs the values whose primary key matches some
9456 given key. Using 1 with a hash-based container, the expected
9457 cost is Θ(n), but the values will not be ordered
9458 by secondary keys (which may or may not be required); using 1
9459 with a tree-based container, the expected cost is
9460 Θ(log(m) + n), but with high constants; again the
9461 values will not be ordered by secondary keys. 2, 3, and 4 are
9462 similar to 1, but typically with lower constants (and,
9463 additionally, if one uses a tree-based container for secondary
9464 keys, they will be ordered). Using 5 with a hash-based
9465 container, the cost is Θ(mn).</para>
9466 <para>Suppose one wants to assign to a primary key all secondary
9467 keys assigned to a different primary key. Using 1 with a
9468 hash-based container, the expected cost is Θ(n),
9469 but with very high constants; using 1 with a tree-based
9470 container, the cost is Θ(nlog(mn)). Using 2, 3,
9471 and 4, the expected cost is Θ(n), but typically
9472 with far lower costs than 1. 5 is similar to 1.</para>
9473
9474 </section>
9475
9476 </section>
9477
9478
9479 <section xml:id="observations.priority_queue">
9480 <info><title>Priority_Queue</title></info>
9481
9482 <section xml:id="observations.priority_queue.complexity">
9483 <info><title>Complexity</title></info>
9484
9485 <para>The following table shows the complexities of the different
9486 underlying data structures in terms of orders of growth. It is
9487 interesting to note that this table implies something about the
9488 constants of the operations as well (see Amortized <function>push</function>
9489 and <function>pop</function> operations).</para>
9490
9491 <informaltable frame="all">
9492
9493 <tgroup cols="6" align="left" colsep="1" rowsep="1">
9494 <colspec colname="c1"/>
9495 <colspec colname="c2"/>
9496 <colspec colname="c3"/>
9497 <colspec colname="c4"/>
9498 <colspec colname="c5"/>
9499 <colspec colname="c6"/>
9500 <thead>
9501 <row>
9502 <entry></entry>
9503 <entry><emphasis><function>push</function></emphasis></entry>
9504 <entry><emphasis><function>pop</function></emphasis></entry>
9505 <entry><emphasis><function>modify</function></emphasis></entry>
9506 <entry><emphasis><function>erase</function></emphasis></entry>
9507 <entry><emphasis><function>join</function></emphasis></entry>
9508 </row>
9509 </thead>
9510
9511 <tbody>
9512
9513 <row>
9514 <entry>
9515 <classname>std::priority_queue</classname>
9516 </entry>
9517 <entry>
9518 Θ(n) worst
9519 Θ(log(n)) amortized
9520 </entry>
9521 <entry>
9522 Θ(log(n)) Worst
9523 </entry>
9524 <entry>
9525 Θ(n log(n)) Worst
9526 <subscript>[std note 1]</subscript>
9527 </entry>
9528 <entry>
9529 Θ(n log(n))
9530 <subscript>[std note 2]</subscript>
9531 </entry>
9532 <entry>
9533 Θ(n log(n))
9534 <subscript>[std note 1]</subscript>
9535 </entry>
9536 </row>
9537 <row>
9538 <entry>
9539 <classname>priority_queue</classname>
9540 &lt;<classname>Tag</classname> =
9541 <classname>pairing_heap_tag</classname>&gt;
9542 </entry>
9543 <entry>
9544 O(1)
9545 </entry>
9546 <entry>
9547 Θ(n) worst
9548 Θ(log(n)) amortized
9549 </entry>
9550 <entry>
9551 Θ(n) worst
9552 Θ(log(n)) amortized
9553 </entry>
9554 <entry>
9555 Θ(n) worst
9556 Θ(log(n)) amortized
9557 </entry>
9558 <entry>
9559 O(1)
9560 </entry>
9561 </row>
9562 <row>
9563 <entry>
9564 <classname>priority_queue</classname>
9565 &lt;<classname>Tag</classname> =
9566 <classname>binary_heap_tag</classname>&gt;
9567 </entry>
9568 <entry>
9569 Θ(n) worst
9570 Θ(log(n)) amortized
9571 </entry>
9572 <entry>
9573 Θ(n) worst
9574 Θ(log(n)) amortized
9575 </entry>
9576 <entry>
9577 Θ(n)
9578 </entry>
9579 <entry>
9580 Θ(n)
9581 </entry>
9582 <entry>
9583 Θ(n)
9584 </entry>
9585 </row>
9586 <row>
9587 <entry>
9588 <classname>priority_queue</classname>
9589 &lt;<classname>Tag</classname> =
9590 <classname>binomial_heap_tag</classname>&gt;
9591 </entry>
9592 <entry>
9593 Θ(log(n)) worst
9594 O(1) amortized
9595 </entry>
9596 <entry>
9597 Θ(log(n))
9598 </entry>
9599 <entry>
9600 Θ(log(n))
9601 </entry>
9602 <entry>
9603 Θ(log(n))
9604 </entry>
9605 <entry>
9606 Θ(log(n))
9607 </entry>
9608 </row>
9609 <row>
9610 <entry>
9611 <classname>priority_queue</classname>
9612 &lt;<classname>Tag</classname> =
9613 <classname>rc_binomial_heap_tag</classname>&gt;
9614 </entry>
9615 <entry>
9616 O(1)
9617 </entry>
9618 <entry>
9619 Θ(log(n))
9620 </entry>
9621 <entry>
9622 Θ(log(n))
9623 </entry>
9624 <entry>
9625 Θ(log(n))
9626 </entry>
9627 <entry>
9628 Θ(log(n))
9629 </entry>
9630 </row>
9631 <row>
9632 <entry>
9633 <classname>priority_queue</classname>&lt;<classname>Tag</classname> =
9634 <classname>thin_heap_tag</classname>&gt;
9635 </entry>
9636 <entry>
9637 O(1)
9638 </entry>
9639 <entry>
9640 Θ(n) worst
9641 Θ(log(n)) amortized
9642 </entry>
9643 <entry>
9644 Θ(log(n)) worst
9645 O(1) amortized,
9646 or Θ(log(n)) amortized
9647 <subscript>[thin_heap_note]</subscript>
9648 </entry>
9649 <entry>
9650 Θ(n) worst
9651 Θ(log(n)) amortized
9652 </entry>
9653 <entry>
9654 Θ(n)
9655 </entry>
9656 </row>
9657 </tbody>
9658 </tgroup>
9659
9660 </informaltable>
9661
9662 <para>[std note 1] This
9663 is not a property of the algorithm, but rather due to the fact
9664 that the standard's priority queue implementation does not support
9665 iterators (and consequently the ability to access a specific
9666 value inside it). If the priority queue is adapting an
9667 <classname>std::vector</classname>, then it is still possible to reduce this
9668 to Θ(n) by adapting over the standard's adapter and
9669 using the fact that <function>top</function> returns a reference to the
9670 first value; if, however, it is adapting an
9671 <classname>std::deque</classname>, then this is impossible.</para>
9672
9673 <para>[std note 2] As
9674 with [std note 1], this is not a
9675 property of the algorithm, but rather the standard's implementation.
9676 Again, if the priority queue is adapting an
9677 <classname>std::vector</classname> then it is possible to reduce this to
9678 Θ(n), but with a very high constant (one must call
9679 <function>std::make_heap</function> which is an expensive linear
9680 operation); if the priority queue is adapting an
9681 <classname>std::deque</classname>, then this is impossible.</para>
9682
9683 <para>[thin_heap_note] A thin heap has
9684 Θ(log(n)) worst case <function>modify</function> time
9685 always, but the amortized time depends on the nature of the
9686 operation: I) if the operation increases the key (in the sense
9687 of the priority queue's comparison functor), then the amortized
9688 time is O(1), but if II) it decreases it, then the
9689 amortized time is the same as the worst case time. Note that
9690 for most algorithms, I) is important and II) is not.</para>
9691
9692 </section>
9693
9694 <section xml:id="observations.priority_queue.amortized_ops">
9695 <info><title>
9696 Amortized <function>push</function>
9697 and <function>pop</function> operations
9698 </title></info>
9699
9700
9701 <para>In many cases, a priority queue is needed primarily for
9702 sequences of <function>push</function> and <function>pop</function> operations. All of
9703 the underlying data structures have the same amortized
9704 logarithmic complexity, but they differ in terms of
9705 constants.</para>
9706 <para>The table above shows that the different data structures are
9707 "constrained" in some respects. In general, if a data structure
9708 has lower worst-case complexity than another, then it will
9709 perform slower in the amortized sense. Thus, for example a
9710 redundant-counter binomial heap (<classname>priority_queue</classname> with
9711 <classname>Tag</classname> = <classname>rc_binomial_heap_tag</classname>)
9712 has lower worst-case <function>push</function> performance than a binomial
9713 heap (<classname>priority_queue</classname>
9714 with <classname>Tag</classname> = <classname>binomial_heap_tag</classname>),
9715 and so its amortized <function>push</function> performance is slower in
9716 terms of constants.</para>
9717 <para>As the table shows, the "least constrained" underlying
9718 data structures are binary heaps and pairing heaps.
9719 Consequently, it is not surprising that they perform best in
9720 terms of amortized constants.</para>
9721 <orderedlist>
9722 <listitem><para>Pairing heaps seem to perform best for non-primitive
9723 types (e.g., <classname>std::string</classname>s), as shown by
9724 Priority
9725 Queue Text <function>push</function> Timing Test and Priority
9726 Queue Text <function>push</function> and <function>pop</function> Timing
9727 Test</para></listitem>
9728 <listitem><para>binary heaps seem to perform best for primitive types
9729 (e.g., <type>int</type>s), as shown by Priority
9730 Queue Random Integer <function>push</function> Timing Test and
9731 Priority
9732 Queue Random Integer <function>push</function> and <function>pop</function> Timing
9733 Test.</para></listitem>
9734 </orderedlist>
9735
9736 </section>
9737
9738 <section xml:id="observations.priority_queue.graphs">
9739 <info><title>
9740 Graph Algorithms
9741 </title></info>
9742
9743 <para>In some graph algorithms, a decrease-key operation is
9744 required [clrs2001];
9745 this operation is identical to <function>modify</function> if a value is
9746 increased (in the sense of the priority queue's comparison
9747 functor). The table above and Priority Queue
9748 Text <function>modify</function> Up Timing Test show that a thin heap
9749 (<classname>priority_queue</classname> with
9750 <classname>Tag</classname> = <classname>thin_heap_tag</classname>)
9751 outperforms a pairing heap (<classname>priority_queue</classname> with
9752 <classname>Tag</classname> = <classname>Tag</classname> = <classname>pairing_heap_tag</classname>),
9753 but the rest of the tests show otherwise.</para>
9754
9755 <para>This makes it difficult to decide which implementation to use in
9756 this case. Dijkstra's shortest-path algorithm, for example, requires
9757 Θ(n) <function>push</function> and <function>pop</function> operations
9758 (in the number of vertices), but O(n<superscript>2</superscript>)
9759 <function>modify</function> operations, which can be in practice Θ(n)
9760 as well. It is difficult to find an a-priori characterization of
9761 graphs in which the actual number of <function>modify</function>
9762 operations will dwarf the number of <function>push</function> and
9763 <function>pop</function> operations.</para>
9764
9765 </section>
9766
9767 </section> <!-- priority_queue -->
9768
9769 </section>
9770
9771
9772 </section> <!-- performance -->
9773
9774 </section>