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