| <section xmlns="http://docbook.org/ns/docbook" version="5.0" | |
| xml:id="pbds.test" xreflabel="Test"> | |
| <info><title>Testing</title></info> | |
| <?dbhtml filename="policy_based_data_structures_test.html"?> | |
| <!-- S01 regression --> | |
| <section xml:id="pbds.test.regression"> | |
| <info><title>Regression</title></info> | |
| <para>The library contains a single comprehensive regression test. | |
| For a given container type in this library, the test creates | |
| an object of the container type and an object of the | |
| corresponding standard type (e.g., <classname>std::set</classname>). It | |
| then performs a random sequence of methods with random | |
| arguments (e.g., inserts, erases, and so forth) on both | |
| objects. At each operation, the test checks the return value of | |
| the method, and optionally both compares this library's | |
| object with the standard's object as well as performing other | |
| consistency checks on this library's object (e.g., | |
| order preservation, when applicable, or node invariants, when | |
| applicable).</para> | |
| <para>Additionally, the test integrally checks exception safety | |
| and resource leaks. This is done as follows. A special | |
| allocator type, written for the purpose of the test, both | |
| randomly throws an exceptions when allocations are performed, | |
| and tracks allocations and de-allocations. The exceptions thrown | |
| at allocations simulate memory-allocation failures; the | |
| tracking mechanism checks for memory-related bugs (e.g., | |
| resource leaks and multiple de-allocations). Both | |
| this library's containers and the containers' value-types are | |
| configured to use this allocator.</para> | |
| <para>For granularity, the test is split into the | |
| several sources, each checking only some containers.</para> | |
| <para>For more details, consult the files in | |
| <filename class="directory">testsuite/ext/pb_ds/regression</filename>. | |
| </para> | |
| </section> | |
| <!-- S02 performance --> | |
| <section xml:id="pbds.test.performance"> | |
| <info><title>Performance</title></info> | |
| <section xml:id="performance.hash"> | |
| <info><title>Hash-Based</title></info> | |
| <para></para> | |
| <!-- 01 <a href="hash_text_find_find_timing_test"> --> | |
| <section xml:id="performance.hash.text_find"> | |
| <info><title> | |
| Text <function>find</function> | |
| </title></info> | |
| <para></para> | |
| <section xml:id="hash.text_find.info"> | |
| <info><title> | |
| Description | |
| </title></info> | |
| <para> | |
| This test inserts a number of values with keys from an | |
| arbitrary text (<xref | |
| linkend="biblio.wickland96thirty"/>) into a container, | |
| then performs a series of finds using | |
| <function>find</function> . It measures the average | |
| time for <function>find</function> as a function of | |
| the number of values inserted.</para> | |
| <para> | |
| It uses the test file: | |
| <filename>performance/ext/pb_ds/text_find_timing_test.cc</filename> | |
| </para> | |
| <para> | |
| And uses the data file: | |
| <filename>filethirty_years_among_the_dead_preproc.txt</filename> | |
| </para> | |
| <para>The test checks the effect of different range-hashing | |
| functions, trigger policies, and cache-hashing policies. | |
| </para> | |
| </section> | |
| <section xml:id="hash.text_find.results"> | |
| <info><title> | |
| Results | |
| </title></info> | |
| <para>The graphic below show the results for the native | |
| and collision-chaining hash types the function | |
| applied being a text find timing test using | |
| <function>find</function>. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="75" | |
| fileref="../images/pbds_hash_text_find.pdf"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_hash_text_find.png"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="5" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <colspec colname="c4"/> | |
| <colspec colname="c5"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| n_hash_map_ncah | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::tr1::unordered_map</classname> | |
| </entry> | |
| <entry> | |
| <classname>cache_hash_code</classname> | |
| </entry> | |
| <entry> | |
| <constant>false</constant> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <!-- hash 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| cc_hash_mod_prime_1div1_nsth_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>cc_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mod_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_prime_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/1 | |
| </entry> | |
| </row> | |
| <!-- hash 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| cc_hash_mask_exp_1div2_sth_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname> | |
| cc_hash_table | |
| </classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| </row> | |
| <!-- hash 03 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| cc_hash_mask_exp_1div1_nsth_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>cc_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/1 | |
| </entry> | |
| </row> | |
| <!-- hash 04 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| cc_hash_mask_exp_1div2_nsth_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>cc_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| </section> | |
| <section xml:id="hash.text_find.observations"> | |
| <info><title> | |
| Observations | |
| </title></info> | |
| <para>In this setting, the range-hashing scheme affects performance | |
| more than other policies. As the results show, containers using | |
| mod-based range-hashing (including the native hash-based container, | |
| which is currently hard-wired to this scheme) have lower performance | |
| than those using mask-based range-hashing. A modulo-based | |
| range-hashing scheme's main benefit is that it takes into account | |
| all hash-value bits. Standard string hash-functions are designed to | |
| create hash values that are nearly-uniform as is (<xref | |
| linkend="biblio.knuth98sorting"/>).</para> | |
| <para>Trigger policies, i.e. the load-checks constants, affect | |
| performance to a lesser extent.</para> | |
| <para>Perhaps surprisingly, storing the hash value alongside each | |
| entry affects performance only marginally, at least in this | |
| library's implementation. (Unfortunately, it was not possible to run | |
| the tests with <classname>std::tr1::unordered_map</classname> 's | |
| <classname>cache_hash_code = true</classname> , as it appeared to | |
| malfuntion.)</para> | |
| </section> | |
| </section> | |
| <!-- 02 <a href="hash_int_find_timing_test"> --> | |
| <section xml:id="performance.hash.int_find"> | |
| <info><title> | |
| Integer <function>find</function> | |
| </title></info> | |
| <para></para> | |
| <section xml:id="hash.int_find.info"> | |
| <info><title> | |
| Description | |
| </title></info> | |
| <para>This test inserts a number of values with uniform | |
| integer keys into a container, then performs a series of finds | |
| using <function>find</function>. It measures the average time | |
| for <function>find</function> as a function of the number of values | |
| inserted.</para> | |
| <para> | |
| It uses the test file: | |
| <filename>performance/ext/pb_ds/random_int_find_timing.cc</filename> | |
| </para> | |
| <para>The test checks the effect of different underlying | |
| hash-tables, | |
| range-hashing functions, and trigger policies.</para> | |
| </section> | |
| <section xml:id="hash.int_find.results"> | |
| <info><title> | |
| Results | |
| </title></info> | |
| <para> | |
| There are two sets of results for this type, one for | |
| collision-chaining hashes, and one for general-probe hashes. | |
| </para> | |
| <para>The first graphic below shows the results for the native and | |
| collision-chaining hash types. The function applied being a random | |
| integer timing test using <function>find</function>. | |
| </para> | |
| <!-- results graphic 01 --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="75" | |
| fileref="../images/pbds_cc_hash_int_find.pdf"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_cc_hash_int_find.png"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="5" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <colspec colname="c4"/> | |
| <colspec colname="c5"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| n_hash_map_ncah | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::tr1::unordered_map</classname> | |
| </entry> | |
| <entry> | |
| <classname>cache_hash_code</classname> | |
| </entry> | |
| <entry> | |
| <constant>false</constant> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <!-- hash 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| cc_hash_mod_prime_1div1_nsth_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>cc_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mod_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_prime_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/1 | |
| </entry> | |
| </row> | |
| <!-- hash 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| cc_hash_mod_prime_1div2_nsth_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname> | |
| cc_hash_table | |
| </classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mod_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_prime_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| </row> | |
| <!-- hash 03 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| cc_hash_mask_exp_1div1_nsth_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>cc_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/1 | |
| </entry> | |
| </row> | |
| <!-- hash 04 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| cc_hash_mask_exp_1div2_nsth_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>cc_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| <para> | |
| </para> | |
| <para> | |
| </para> | |
| <para>And the second graphic shows the results for the native and | |
| general-probe hash types. The function applied being a random | |
| integer timing test using <function>find</function>. | |
| </para> | |
| <!-- results graphic 02 --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="75" | |
| fileref="../images/pbds_gp_hash_int_find.pdf"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_gp_hash_int_find.png"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="5" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <colspec colname="c4"/> | |
| <colspec colname="c5"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| n_hash_map_ncah | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::tr1::unordered_map</classname> | |
| </entry> | |
| <entry> | |
| <classname>cache_hash_code</classname> | |
| </entry> | |
| <entry> | |
| <constant>false</constant> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <!-- hash 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| gp_hash_mod_quadp_prime_1div2_nsth_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="3" valign="top"> | |
| <classname>gp_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mod_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Probe_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>quadratic_probe_fn</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_prime_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| </row> | |
| <!-- hash 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| gp_hash_mask_linp_exp_1div2_nsth_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="3" valign="top"> | |
| <classname> | |
| gp_hash_table | |
| </classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Probe_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>linear_probe_fn</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| </section> | |
| <section xml:id="hash.int_find.observations"> | |
| <info><title> | |
| Observations | |
| </title></info> | |
| <para>In this setting, the choice of underlying hash-table affects | |
| performance most, then the range-hashing scheme and, only finally, | |
| other policies.</para> | |
| <para>When comparing probing and chaining containers, it is | |
| apparent that the probing containers are less efficient than the | |
| collision-chaining containers ( | |
| <classname>std::tr1::unordered_map</classname> uses | |
| collision-chaining) in this case.</para> | |
| <para>Hash-Based Integer Subscript Insert Timing Test shows | |
| a different case, where the situation is reversed; | |
| </para> | |
| <para>Within each type of hash-table, the range-hashing scheme | |
| affects performance more than other policies; Hash-Based Text | |
| <function>find</function> Find Timing Test also shows this. In the | |
| above graphics should be noted that | |
| <classname>std::tr1::unordered_map</classname> are hard-wired | |
| currently to mod-based schemes. | |
| </para> | |
| </section> | |
| </section> | |
| <!-- 03 <a href="hash_int_subscript_find_test"> --> | |
| <section xml:id="performance.hash.int_subscript_find"> | |
| <info><title> | |
| Integer Subscript <function>find</function> | |
| </title></info> | |
| <para></para> | |
| <section xml:id="hash.int_subscript_find.info"> | |
| <info><title> | |
| Description | |
| </title></info> | |
| <para>This test inserts a number of values with uniform | |
| integer keys into a container, then performs a series of finds | |
| using <function>operator[]</function>. It measures the average time | |
| for <function>operator[]</function> as a function of the number of | |
| values inserted.</para> | |
| <para> | |
| It uses the test file: | |
| <filename>performance/ext/pb_ds/random_int_subscript_find_timing.cc</filename> | |
| </para> | |
| <para>The test checks the effect of different underlying | |
| hash-tables, range-hashing functions, and trigger policies.</para> | |
| </section> | |
| <section xml:id="hash.int_subscript_find.results"> | |
| <info><title> | |
| Results | |
| </title></info> | |
| <para> | |
| There are two sets of results for this type, one for | |
| collision-chaining hashes, and one for general-probe hashes. | |
| </para> | |
| <para>The first graphic below shows the results for the native | |
| and collision-chaining hash types, using as the function | |
| applied an integer subscript timing test with | |
| <function>find</function>. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="75" | |
| fileref="../images/pbds_cc_hash_int_subscript_find.pdf"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_cc_hash_int_subscript_find.png"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="5" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <colspec colname="c4"/> | |
| <colspec colname="c5"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| n_hash_map_ncah | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::tr1::unordered_map</classname> | |
| </entry> | |
| <entry> | |
| <classname>cache_hash_code</classname> | |
| </entry> | |
| <entry> | |
| <constant>false</constant> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <!-- hash 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| cc_hash_mod_prime_1div1_nsth_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>cc_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mod_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_prime_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/1 | |
| </entry> | |
| </row> | |
| <!-- hash 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| cc_hash_mod_prime_1div2_nsth_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>cc_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mod_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_prime_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| </row> | |
| <!-- hash 03 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| cc_hash_mask_exp_1div1_nsth_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>cc_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/1 | |
| </entry> | |
| </row> | |
| <!-- hash 04 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| cc_hash_mask_exp_1div2_nsth_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>cc_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| <para> | |
| </para> | |
| <para> | |
| </para> | |
| <para>And the second graphic shows the results for the native and | |
| general-probe hash types. The function applied being a random | |
| integer timing test using <function>find</function>. | |
| </para> | |
| <!-- results graphic 02 --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="75" | |
| fileref="../images/pbds_gp_hash_int_subscript_find.pdf"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_gp_hash_int_subscript_find.png"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="5" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <colspec colname="c4"/> | |
| <colspec colname="c5"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| n_hash_map_ncah | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::tr1::unordered_map</classname> | |
| </entry> | |
| <entry> | |
| <classname>cache_hash_code</classname> | |
| </entry> | |
| <entry> | |
| <constant>false</constant> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <!-- hash 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| gp_hash_mod_quadp_prime_1div2_nsth_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="3" valign="top"> | |
| <classname>gp_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mod_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Probe_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>quadratic_probe_fn</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_prime_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| </row> | |
| <!-- hash 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| gp_hash_mask_linp_exp_1div2_nsth_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="3" valign="top"> | |
| <classname> | |
| gp_hash_table | |
| </classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Probe_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>linear_probe_fn</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| </section> | |
| <section xml:id="hash.int_subscript_find.observations"> | |
| <info><title> | |
| Observations | |
| </title></info> | |
| <para>This test shows similar results to Hash-Based | |
| Integer <classname>find</classname> Find Timing test.</para> | |
| </section> | |
| </section> | |
| <!-- 04 <a href="hash_random_int_subscript_insert_timing_test"> --> | |
| <section xml:id="performance.hash.int_subscript_insert"> | |
| <info><title> | |
| Integer Subscript <function>insert</function> | |
| </title></info> | |
| <para></para> | |
| <section xml:id="hash.int_subscript_insert.info"> | |
| <info><title> | |
| Description | |
| </title></info> | |
| <para>This test inserts a number of values with uniform i.i.d. | |
| integer keys into a container, using | |
| <function>operator[]</function>. It measures the average time for | |
| <function>operator[]</function> as a function of the number of | |
| values inserted.</para> | |
| <para> | |
| It uses the test file: | |
| <filename>performance/ext/pb_ds/random_int_subscript_insert_timing.cc</filename> | |
| </para> | |
| <para>The test checks the effect of different underlying | |
| hash-tables.</para> | |
| </section> | |
| <section xml:id="hash.int_subscript_insert.results"> | |
| <info><title> | |
| Results | |
| </title></info> | |
| <para> | |
| There are two sets of results for this type, one for | |
| collision-chaining hashes, and one for general-probe hashes. | |
| </para> | |
| <para>The first graphic below shows the results for the native | |
| and collision-chaining hash types, using as the function | |
| applied an integer subscript timing test with | |
| <function>insert</function>. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="75" | |
| fileref="../images/pbds_cc_hash_int_subscript_insert.pdf"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_cc_hash_int_subscript_insert.png"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="5" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <colspec colname="c4"/> | |
| <colspec colname="c5"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| n_hash_map_ncah | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::tr1::unordered_map</classname> | |
| </entry> | |
| <entry> | |
| <classname>cache_hash_code</classname> | |
| </entry> | |
| <entry> | |
| <constant>false</constant> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <!-- hash 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| cc_hash_mod_prime_1div1_nsth_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>cc_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mod_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_prime_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/1 | |
| </entry> | |
| </row> | |
| <!-- hash 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| cc_hash_mod_prime_1div2_nsth_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>cc_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mod_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_prime_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| </row> | |
| <!-- hash 03 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| cc_hash_mask_exp_1div1_nsth_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>cc_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/1 | |
| </entry> | |
| </row> | |
| <!-- hash 04 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| cc_hash_mask_exp_1div2_nsth_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>cc_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| <para> | |
| </para> | |
| <para> | |
| </para> | |
| <para>And the second graphic shows the results for the native and | |
| general-probe hash types. The function applied being a random | |
| integer timing test using <function>find</function>. | |
| </para> | |
| <!-- results graphic 02 --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="75" | |
| fileref="../images/pbds_gp_hash_int_subscript_insert.pdf"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_gp_hash_int_subscript_insert.png"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="5" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <colspec colname="c4"/> | |
| <colspec colname="c5"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| n_hash_map_ncah | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::tr1::unordered_map</classname> | |
| </entry> | |
| <entry> | |
| <classname>cache_hash_code</classname> | |
| </entry> | |
| <entry> | |
| <constant>false</constant> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <!-- hash 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| gp_hash_mod_quadp_prime_1div2_nsth_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="3" valign="top"> | |
| <classname>gp_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mod_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Probe_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>quadratic_probe_fn</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_prime_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| </row> | |
| <!-- hash 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| gp_hash_mask_linp_exp_1div2_nsth_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="3" valign="top"> | |
| <classname> | |
| gp_hash_table | |
| </classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Probe_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>linear_probe_fn</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| </section> | |
| <section xml:id="hash.int_subscript_insert.observations"> | |
| <info><title> | |
| Observations | |
| </title></info> | |
| <para>In this setting, as in Hash-Based Text | |
| <function>find</function> Find Timing test and Hash-Based | |
| Integer <function>find</function> Find Timing test , the choice | |
| of underlying hash-table underlying hash-table affects performance | |
| most, then the range-hashing scheme, and | |
| finally any other policies.</para> | |
| <para>There are some differences, however:</para> | |
| <orderedlist> | |
| <listitem><para>In this setting, probing tables function sometimes more | |
| efficiently than collision-chaining tables. | |
| This is explained shortly.</para></listitem> | |
| <listitem><para>The performance graphs have a "saw-tooth" shape. The | |
| average insert time rises and falls. As values are inserted | |
| into the container, the load factor grows larger. Eventually, | |
| a resize occurs. The reallocations and rehashing are | |
| relatively expensive. After this, the load factor is smaller | |
| than before.</para></listitem> | |
| </orderedlist> | |
| <para>Collision-chaining containers use indirection for greater | |
| flexibility; probing containers store values contiguously, in | |
| an array (see Figure Motivation::Different | |
| underlying data structures A and B, respectively). It | |
| follows that for simple data types, probing containers access | |
| their allocator less frequently than collision-chaining | |
| containers, (although they still have less efficient probing | |
| sequences). This explains why some probing containers fare | |
| better than collision-chaining containers in this case.</para> | |
| <para> | |
| Within each type of hash-table, the range-hashing scheme affects | |
| performance more than other policies. This is similar to the | |
| situation in Hash-Based Text | |
| <function>find</function> Find Timing Test and Hash-Based | |
| Integer <function>find</function> Find Timing Test. | |
| Unsurprisingly, however, containers with lower α<subscript>max</subscript> perform worse in this case, | |
| since more re-hashes are performed.</para> | |
| </section> | |
| </section> | |
| <!-- 05 <a href="hash_zlob_random_int_find_find_timing_test"> --> | |
| <!-- 05 <a href="hash_zlob_random_int_find_find_timing_test"> --> | |
| <section xml:id="performance.hash.zlob_int_find"> | |
| <info><title> | |
| Integer <function>find</function> with Skewed-Distribution | |
| </title></info> | |
| <para></para> | |
| <section xml:id="hash.zlob_int_find.info"> | |
| <info><title> | |
| Description | |
| </title></info> | |
| <para>This test inserts a number of values with a markedly | |
| non-uniform integer keys into a container, then performs | |
| a series of finds using <function>find</function>. It measures the average | |
| time for <function>find</function> as a function of the number of values in | |
| the containers. The keys are generated as follows. First, a | |
| uniform integer is created. Then it is then shifted left 8 bits.</para> | |
| <para> | |
| It uses the test file: | |
| <filename>performance/ext/pb_ds/hash_zlob_random_int_find_timing.cc</filename> | |
| </para> | |
| <para>The test checks the effect of different range-hashing | |
| functions and trigger policies.</para> | |
| </section> | |
| <section xml:id="hash.zlob_int_find.results"> | |
| <info><title> | |
| Results | |
| </title></info> | |
| <para>The graphic below show the results for the native, collision-chaining, and general-probing hash types. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="75" | |
| fileref="../images/pbds_hash_zlob_int_find.pdf"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_hash_zlob_int_find.png"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="5" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <colspec colname="c4"/> | |
| <colspec colname="c5"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| n_hash_map_ncah | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::tr1::unordered_map</classname> | |
| </entry> | |
| <entry> | |
| <classname>cache_hash_code</classname> | |
| </entry> | |
| <entry> | |
| <constant>false</constant> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <!-- hash 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| cc_hash_mod_prime_1div1_nsth_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>cc_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mod_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_prime_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/1 | |
| </entry> | |
| </row> | |
| <!-- hash 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| cc_hash_mask_exp_1div1_nsth_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname> | |
| cc_hash_table | |
| </classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/1 | |
| </entry> | |
| </row> | |
| <!-- hash 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| gp_hash_mod_quadp_prime_1div2_nsth_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="3" valign="top"> | |
| <classname>gp_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mod_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Probe_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>quadratic_probe_fn</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_prime_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| </section> | |
| <section xml:id="hash.zlob_int_find.observations"> | |
| <info><title> | |
| Observations | |
| </title></info> | |
| <para>In this setting, the distribution of keys is so skewed that | |
| the underlying hash-table type affects performance marginally. | |
| (This is in contrast with Hash-Based Text | |
| <function>find</function> Find Timing Test, Hash-Based | |
| Integer <function>find</function> Find Timing Test, Hash-Based | |
| Integer Subscript Find Timing Test and Hash-Based | |
| Integer Subscript Insert Timing Test.)</para> | |
| <para>The range-hashing scheme affects performance dramatically. A | |
| mask-based range-hashing scheme effectively maps all values | |
| into the same bucket. Access degenerates into a search within | |
| an unordered linked-list. In the graphic above, it should be noted that | |
| <classname>std::tr1::unordered_map</classname> is hard-wired currently to mod-based and mask-based schemes, | |
| respectively.</para> | |
| <para>When observing the settings of this test, it is apparent | |
| that the keys' distribution is far from natural. One might ask | |
| if the test is not contrived to show that, in some cases, | |
| mod-based range hashing does better than mask-based range | |
| hashing. This is, in fact just the case. A | |
| more natural case in which mod-based range hashing is better was not encountered. | |
| Thus the inescapable conclusion: real-life key distributions are handled better | |
| with an appropriate hash function and a mask-based | |
| range-hashing function. (<filename>pb_ds/example/hash_shift_mask.cc</filename> | |
| shows an example of handling this a-priori known skewed | |
| distribution with a mask-based range-hashing function). If hash | |
| performance is bad, a χ<superscript>2</superscript> test can be used | |
| to check how to transform it into a more uniform | |
| distribution.</para> | |
| <para>For this reason, this library's default range-hashing | |
| function is mask-based.</para> | |
| </section> | |
| </section> | |
| <!-- 06 <a href="hash_random_int_erase_mem_usage_test"> --> | |
| <!-- 06 <a href="hash_random_int_erase_mem_usage_test"> --> | |
| <section xml:id="performance.hash.erase_mem"> | |
| <info><title> | |
| Erase Memory Use | |
| </title></info> | |
| <para></para> | |
| <section xml:id="hash.erase_mem.info"> | |
| <info><title> | |
| Description | |
| </title></info> | |
| <para>This test inserts a number of uniform integer keys | |
| into a container, then erases all keys except one. It measures | |
| the final size of the container.</para> | |
| <para> | |
| It uses the test file: | |
| <filename>performance/ext/pb_ds/hash_random_int_erase_mem_usage.cc</filename> | |
| </para> | |
| <para>The test checks how containers adjust internally as their | |
| logical size decreases.</para> | |
| </section> | |
| <section xml:id="hash.erase_mem.results"> | |
| <info><title> | |
| Results | |
| </title></info> | |
| <para>The graphic below show the results for the native, collision-chaining, and general-probing hash types. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="75" | |
| fileref="../images/pbds_hash_int_erase_mem.pdf"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_hash_int_erase_mem.png"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="5" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <colspec colname="c4"/> | |
| <colspec colname="c5"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| n_hash_map_ncah | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::tr1::unordered_map</classname> | |
| </entry> | |
| <entry> | |
| <classname>cache_hash_code</classname> | |
| </entry> | |
| <entry> | |
| <constant>false</constant> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <!-- hash 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| cc_hash_mod_prime_1div1_nsth_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>cc_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mod_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_prime_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/1 | |
| </entry> | |
| </row> | |
| <!-- hash 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| cc_hash_mask_exp_1div2_nsth_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname> | |
| cc_hash_table | |
| </classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| </row> | |
| <!-- hash 03 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c5"> | |
| gp_hash_mask_linp_exp_1div2_nsth_set | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="3" valign="top"> | |
| <classname>gp_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Probe_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>linear_probe_fn</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c5"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| </section> | |
| <section xml:id="hash.erase_mem.observations"> | |
| <info><title> | |
| Observations | |
| </title></info> | |
| <para>The standard's hash-based containers act very differently than trees in | |
| this respect. When erasing numerous keys from an standard | |
| associative-container, the resulting memory user varies greatly | |
| depending on whether the container is tree-based or hash-based. | |
| This is a fundamental consequence of the standard's interface for | |
| associative containers, and it is not due to a specific | |
| implementation.</para> | |
| </section> | |
| </section> | |
| </section> | |
| <section xml:id="performance.branch"> | |
| <info><title>Branch-Based</title></info> | |
| <para></para> | |
| <!-- 01 <a href="tree_text_insert_timing_test"> --> | |
| <section xml:id="performance.branch.text_insert"> | |
| <info><title> | |
| Text <function>insert</function> | |
| </title></info> | |
| <para></para> | |
| <section xml:id="branch.text_insert.info"> | |
| <info><title> | |
| Description | |
| </title></info> | |
| <para>This test inserts a number of values with keys from an arbitrary | |
| text ([wickland96thirty]) into a container | |
| using <function>insert</function> . It measures the average time | |
| for <function>insert</function> as a function of the number of | |
| values inserted.</para> | |
| <para>The test checks the effect of different underlying | |
| data structures.</para> | |
| <para> | |
| It uses the test file: | |
| <filename>performance/ext/pb_ds/tree_text_insert_timing.cc</filename> | |
| </para> | |
| </section> | |
| <section xml:id="branch.text_insert.results"> | |
| <info><title> | |
| Results | |
| </title></info> | |
| <para>The three graphics below show the results for the native | |
| tree and this library's node-based trees, the native tree and | |
| this library's vector-based trees, and the native tree | |
| and this library's PATRICIA-trie, respectively. | |
| </para> | |
| <para>The graphic immediately below shows the results for the | |
| native tree type and several node-based tree types. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="75" | |
| fileref="../images/pbds_tree_text_insert_node.pdf"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_tree_text_insert_node.png"/> | |
| </imageobject> | |
| </mediaobject> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| </informalfigure> | |
| <informaltable frame="all"> | |
| <tgroup cols="3" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| n_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::map</classname> | |
| </entry> | |
| <entry namest="c2" nameend="c3"></entry> | |
| </row> | |
| <!-- branch 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| splay_tree_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>tree</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>splay_tree_tag</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Node_update</classname> | |
| </entry> | |
| <entry> | |
| <classname>null_node_update</classname> | |
| </entry> | |
| </row> | |
| <!-- branch 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| rb_tree_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>tree</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>rb_tree_tag</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Node_update</classname> | |
| </entry> | |
| <entry> | |
| <classname>null_node_update</classname> | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| <para>The graphic below shows the results for the | |
| native tree type and a vector-based tree type. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="75" | |
| fileref="../images/pbds_tree_text_insert_vector.pdf"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_tree_text_insert_vector.png"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="3" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| n_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::map</classname> | |
| </entry> | |
| <entry namest="c2" nameend="c3"></entry> | |
| </row> | |
| <!-- branch 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| ov_tree_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>tree</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>ov_tree_tag</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Node_update</classname> | |
| </entry> | |
| <entry> | |
| <classname>null_node_update</classname> | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| <para>The graphic below shows the results for the | |
| native tree type and a PATRICIA trie type. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="75" | |
| fileref="../images/pbds_tree_text_insert_trie.pdf"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_tree_text_insert_trie.png"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="3" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| n_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::map</classname> | |
| </entry> | |
| <entry namest="c2" nameend="c3"></entry> | |
| </row> | |
| <!-- branch 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| pat_trie_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>tree</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>pat_trie_tag</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Node_update</classname> | |
| </entry> | |
| <entry> | |
| <classname>null_node_update</classname> | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| </section> | |
| <section xml:id="branch.text_insert.observations"> | |
| <info><title> | |
| Observations | |
| </title></info> | |
| <para>Observing the first graphic implies that for this setting, a splay tree | |
| (<classname>tree</classname> with <classname>Tag | |
| </classname> = <classname>splay_tree_tag</classname>) does not do | |
| well. See also the Branch-Based | |
| Text <function>find</function> Find Timing Test. The two | |
| red-black trees perform better.</para> | |
| <para>Observing the second graphic, an ordered-vector tree | |
| (<classname>tree</classname> with <classname>Tag | |
| </classname> = <classname>ov_tree_tag</classname>) performs | |
| abysmally. Inserting into this type of tree has linear complexity | |
| [ austern00noset].</para> | |
| <para>Observing the third and last graphic, A PATRICIA trie | |
| (<classname>trie</classname> with <classname>Tag | |
| </classname> = <classname>pat_trie_tag</classname>) has abysmal | |
| performance, as well. This is not that surprising, since a | |
| large-fan-out PATRICIA trie works like a hash table with | |
| collisions resolved by a sub-trie. Each time a collision is | |
| encountered, a new "hash-table" is built A large fan-out PATRICIA | |
| trie, however, doe does well in look-ups (see Branch-Based | |
| Text <function>find</function> Find Timing Test). It may be | |
| beneficial in semi-static settings.</para> | |
| </section> | |
| </section> | |
| <!-- 02 <a href="tree_text_find_find_timing_test"> --> | |
| <section xml:id="performance.branch.text_find"> | |
| <info><title> | |
| Text <function>find</function> | |
| </title></info> | |
| <para></para> | |
| <section xml:id="branch.text_find.info"> | |
| <info><title> | |
| Description | |
| </title></info> | |
| <para>This test inserts a number of values with keys from an | |
| arbitrary text ([wickland96thirty]) into | |
| a container, then performs a series of finds using | |
| <function>find</function>. It measures the average time | |
| for <function>find</function> as a function of the number of | |
| values inserted.</para> | |
| <para> | |
| It uses the test file: | |
| <filename>performance/ext/pb_ds/text_find_timing.cc</filename> | |
| </para> | |
| <para>The test checks the effect of different underlying | |
| data structures.</para> | |
| </section> | |
| <section xml:id="branch.text_find.results"> | |
| <info><title> | |
| Results | |
| </title></info> | |
| <para>The graphic immediately below shows the results for the | |
| native tree type and several other tree types. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="75" | |
| fileref="../images/pbds_tree_text_find.pdf"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_tree_text_find.png"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="3" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| n_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::map</classname> | |
| </entry> | |
| <entry namest="c2" nameend="c3"></entry> | |
| </row> | |
| <!-- branch 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| splay_tree_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>tree</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>splay_tree_tag</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Node_Update</classname> | |
| </entry> | |
| <entry> | |
| <classname>null_node_update</classname> | |
| </entry> | |
| </row> | |
| <!-- branch 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| rb_tree_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>tree</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>rb_tree_tag</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Node_Update</classname> | |
| </entry> | |
| <entry> | |
| <classname>null_node_update</classname> | |
| </entry> | |
| </row> | |
| <!-- branch 03 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| ov_tree_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>tree</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>ov_tree_tag</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Node_Update</classname> | |
| </entry> | |
| <entry> | |
| <classname>null_node_update</classname> | |
| </entry> | |
| </row> | |
| <!-- branch 05 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| pat_trie_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>tree</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>pat_trie_tag</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Node_Update</classname> | |
| </entry> | |
| <entry> | |
| <classname>null_node_update</classname> | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| </section> | |
| <section xml:id="branch.text_find.observations"> | |
| <info><title> | |
| Observations | |
| </title></info> | |
| <para>For this setting, a splay tree (<classname>tree</classname> | |
| with <classname>Tag | |
| </classname> = <classname>splay_tree_tag</classname>) does not do | |
| well. This is possibly due to two reasons:</para> | |
| <orderedlist> | |
| <listitem><para>A splay tree is not guaranteed to be balanced [motwani95random]. If a | |
| splay tree contains n nodes, its average root-leaf | |
| path can be m >> log(n).</para></listitem> | |
| <listitem><para>Assume a specific root-leaf search path has length | |
| m, and the search-target node has distance m' | |
| from the root. A red-black tree will require m + 1 | |
| comparisons to find the required node; a splay tree will | |
| require 2 m' comparisons. A splay tree, consequently, | |
| can perform many more comparisons than a red-black tree.</para></listitem> | |
| </orderedlist> | |
| <para>An ordered-vector tree (<classname>tree</classname> | |
| with <classname>Tag</classname> = <classname>ov_tree_tag</classname>), a red-black | |
| tree (<classname>tree</classname> | |
| with <classname>Tag</classname> = <classname>rb_tree_tag</classname>), and the | |
| native red-black tree all share approximately the same | |
| performance.</para> | |
| <para>An ordered-vector tree is slightly slower than red-black | |
| trees, since it requires, in order to find a key, more math | |
| operations than they do. Conversely, an ordered-vector tree | |
| requires far lower space than the others. ([austern00noset], however, | |
| seems to have an implementation that is also faster than a | |
| red-black tree).</para> | |
| <para>A PATRICIA trie (<classname>trie</classname> | |
| with <classname>Tag</classname> = <classname>pat_trie_tag</classname>) has good | |
| look-up performance, due to its large fan-out in this case. In | |
| this setting, a PATRICIA trie has look-up performance comparable | |
| to a hash table (see Hash-Based Text | |
| <classname>find</classname> Timing Test), but it is order | |
| preserving. This is not that surprising, since a large-fan-out | |
| PATRICIA trie works like a hash table with collisions resolved | |
| by a sub-trie. A large-fan-out PATRICIA trie does not do well on | |
| modifications (see Tree-Based and Trie-Based | |
| Text Insert Timing Test). Therefore, it is possibly beneficial in | |
| semi-static settings.</para> | |
| </section> | |
| </section> | |
| <!-- 03 <a href="tree_text_lor_find_find_timing_test"> --> | |
| <section xml:id="performance.branch.text_lor_find"> | |
| <info><title> | |
| Text <function>find</function> with Locality-of-Reference | |
| </title></info> | |
| <para></para> | |
| <section xml:id="branch.text_lor_find.info"> | |
| <info><title> | |
| Description | |
| </title></info> | |
| <para>This test inserts a number of values with keys from an | |
| arbitrary text ([wickland96thirty]) into | |
| a container, then performs a series of finds using | |
| <function>find</function>. It is different than Tree-Based and | |
| Trie-Based Text <function>find</function> Find Timing Test in the | |
| sequence of finds it performs: this test performs multiple | |
| <function>find</function>s on the same key before moving on to the next | |
| key. It measures the average time for <function>find</function> as a | |
| function of the number of values inserted.</para> | |
| <para> | |
| It uses the test file: | |
| <filename>performance/ext/pb_ds/tree_text_lor_find_timing.cc</filename> | |
| </para> | |
| <para>The test checks the effect of different underlying | |
| data structures in a locality-of-reference setting.</para> | |
| </section> | |
| <section xml:id="branch.text_lor_find.results"> | |
| <info><title> | |
| Results | |
| </title></info> | |
| <para>The graphic immediately below shows the results for the | |
| native tree type and several other tree types. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="75" | |
| fileref="../images/pbds_tree_text_lor_find.pdf"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_tree_text_lor_find.png"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="3" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| n_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::map</classname> | |
| </entry> | |
| <entry namest="c2" nameend="c3"></entry> | |
| </row> | |
| <!-- branch 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| splay_tree_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>tree</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>splay_tree_tag</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Node_Update</classname> | |
| </entry> | |
| <entry> | |
| <classname>null_node_update</classname> | |
| </entry> | |
| </row> | |
| <!-- branch 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| rb_tree_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>tree</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>rb_tree_tag</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Node_Update</classname> | |
| </entry> | |
| <entry> | |
| <classname>null_node_update</classname> | |
| </entry> | |
| </row> | |
| <!-- branch 03 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| ov_tree_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>tree</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>ov_tree_tag</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Node_Update</classname> | |
| </entry> | |
| <entry> | |
| <classname>null_node_update</classname> | |
| </entry> | |
| </row> | |
| <!-- branch 05 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| pat_trie_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>tree</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>pat_trie_tag</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Node_Update</classname> | |
| </entry> | |
| <entry> | |
| <classname>null_node_update</classname> | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| </section> | |
| <section xml:id="branch.text_lor_find.observations"> | |
| <info><title> | |
| Observations | |
| </title></info> | |
| <para>For this setting, an ordered-vector tree | |
| (<classname>tree</classname> with <classname>Tag</classname> | |
| = <classname>ov_tree_tag</classname>), a red-black tree | |
| (<classname>tree</classname> with <classname>Tag</classname> | |
| = <classname>rb_tree_tag</classname>), and the native red-black | |
| tree all share approximately the same performance.</para> | |
| <para>A splay tree (<classname>tree</classname> | |
| with <classname>Tag</classname> = <classname>splay_tree_tag</classname>) does | |
| much better, since each (successful) find "bubbles" the | |
| corresponding node to the root of the tree.</para> | |
| </section> | |
| </section> | |
| <!-- 04 <a href="tree_split_join_timing_test"> --> | |
| <section xml:id="performance.branch.split_join"> | |
| <info><title> | |
| <function>split</function> and <function>join</function> | |
| </title></info> | |
| <para></para> | |
| <section xml:id="branch.split_join.info"> | |
| <info><title> | |
| Description | |
| </title></info> | |
| <para>This test a container, inserts into a number of values, splits | |
| the container at the median, and joins the two containers. (If the | |
| containers are one of this library's trees, | |
| it splits and joins with the <function>split</function> and | |
| <function>join</function> method; otherwise, it uses the <function>erase</function> and | |
| <function>insert</function> methods.) It measures the time for splitting | |
| and joining the containers as a function of the number of | |
| values inserted.</para> | |
| <para> | |
| It uses the test file: | |
| <filename>performance/ext/pb_ds/tree_split_join_timing.cc</filename> | |
| </para> | |
| <para>The test checks the performance difference of <function>join</function> | |
| as opposed to a sequence of <function>insert</function> operations; by | |
| implication, this test checks the most efficient way to erase a | |
| sub-sequence from a tree-like-based container, since this can | |
| always be performed by a small sequence of splits and joins. | |
| </para> | |
| </section> | |
| <section xml:id="branch.split_join.results"> | |
| <info><title> | |
| Results | |
| </title></info> | |
| <para>The graphic immediately below shows the results for the | |
| native tree type and several other tree types. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="75" | |
| fileref="../images/pbds_tree_split_join.pdf"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_tree_split_join.png"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="3" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| n_set | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::set</classname> | |
| </entry> | |
| <entry namest="c2" nameend="c3"></entry> | |
| </row> | |
| <!-- branch 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| splay_tree_set | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>tree</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>splay_tree_tag</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Node_Update</classname> | |
| </entry> | |
| <entry> | |
| <classname>null_node_update</classname> | |
| </entry> | |
| </row> | |
| <!-- branch 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| rb_tree_set | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>tree</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>rb_tree_tag</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Node_Update</classname> | |
| </entry> | |
| <entry> | |
| <classname>null_node_update</classname> | |
| </entry> | |
| </row> | |
| <!-- branch 03 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| ov_tree_set | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>tree</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>ov_tree_tag</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Node_Update</classname> | |
| </entry> | |
| <entry> | |
| <classname>null_node_update</classname> | |
| </entry> | |
| </row> | |
| <!-- branch 05 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| pat_trie_map | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>tree</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>pat_trie_tag</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Node_Update</classname> | |
| </entry> | |
| <entry> | |
| <classname>null_node_update</classname> | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| </section> | |
| <section xml:id="branch.split_join.observations"> | |
| <info><title> | |
| Observations | |
| </title></info> | |
| <para>In this test, the native red-black trees must be split and | |
| joined externally, through a sequence of <function>erase</function> and | |
| <function>insert</function> operations. This is clearly | |
| super-linear, and it is not that surprising that the cost is | |
| high.</para> | |
| <para>This library's tree-based containers use in this test the | |
| <function>split</function> and <function>join</function> methods, | |
| which have lower complexity: the <function>join</function> method | |
| of a splay tree (<classname>tree</classname> | |
| with <classname>Tag </classname> | |
| = <classname>splay_tree_tag</classname>) is quadratic in the | |
| length of the longest root-leaf path, and linear in the total | |
| number of elements; the <function>join</function> method of a | |
| red-black tree (<classname>tree</classname> | |
| with <classname>Tag </classname> | |
| = <classname>rb_tree_tag</classname>) or an ordered-vector tree | |
| (<classname>tree</classname> with <classname>Tag </classname> | |
| = <classname>ov_tree_tag</classname>) is linear in the number of | |
| elements.</para> | |
| <para>Asides from orders of growth, this library's trees access their | |
| allocator very little in these operations, and some of them do not | |
| access it at all. This leads to lower constants in their | |
| complexity, and, for some containers, to exception-free splits and | |
| joins (which can be determined | |
| via <classname>container_traits</classname>).</para> | |
| <para>It is important to note that <function>split</function> and | |
| <function>join</function> are not esoteric methods - they are the most | |
| efficient means of erasing a contiguous range of values from a | |
| tree based container.</para> | |
| </section> | |
| </section> | |
| <!-- 05 <a href="tree_order_statistics_timing_test"> --> | |
| <section xml:id="performance.branch.order_statistics"> | |
| <info><title> | |
| Order-Statistics | |
| </title></info> | |
| <para></para> | |
| <section xml:id="branch.order_statistics.info"> | |
| <info><title> | |
| Description | |
| </title></info> | |
| <para>This test creates a container, inserts random integers into the | |
| the container, and then checks the order-statistics of the | |
| container's values. (If the container is one of this | |
| library's trees, it does this with | |
| the <function>order_of_key</function> method of | |
| <classname>tree_order_statistics_node_update</classname> | |
| ; otherwise, it uses the <function>find</function> method and | |
| <function>std::distance</function>.) It measures the average | |
| time for such queries as a function of the number of values | |
| inserted.</para> | |
| <para> | |
| It uses the test file: | |
| <filename>performance/ext/pb_ds/tree_order_statistics_timing.cc</filename> | |
| </para> | |
| <para>The test checks the performance difference of policies based | |
| on node-invariant as opposed to a external functions.</para> | |
| </section> | |
| <section xml:id="branch.order_statistics.results"> | |
| <info><title> | |
| Results | |
| </title></info> | |
| <para>The graphic immediately below shows the results for the | |
| native tree type and several other tree types. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="75" | |
| fileref="../images/pbds_tree_order_statistics.pdf"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_tree_order_statistics.png"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="3" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| n_set | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::set</classname> | |
| </entry> | |
| <entry namest="c2" nameend="c3"></entry> | |
| </row> | |
| <!-- branch 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| splay_tree_ost_set | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>tree</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>splay_tree_tag</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Node_Update</classname> | |
| </entry> | |
| <entry> | |
| <classname>tree_order_statistics_node_update</classname> | |
| </entry> | |
| </row> | |
| <!-- branch 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| rb_tree_ost_set | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>tree</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>rb_tree_tag</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Node_Update</classname> | |
| </entry> | |
| <entry> | |
| <classname>tree_order_statistics_node_update</classname> | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| </section> | |
| <section xml:id="branch.order_statistics.observations"> | |
| <info><title> | |
| Observations | |
| </title></info> | |
| <para>In this test, the native red-black tree can support | |
| order-statistics queries only externally, by performing a | |
| <classname>find</classname> (alternatively, <classname>lower_bound</classname> or | |
| <classname>upper_bound</classname> ) and then using <classname>std::distance</classname> . | |
| This is clearly linear, and it is not that surprising that the | |
| cost is high.</para> | |
| <para>This library's tree-based containers use in this test the | |
| <classname>order_of_key</classname> method of <classname>tree_order_statistics_node_update</classname>. | |
| This method has only linear complexity in the length of the | |
| root-node path. Unfortunately, the average path of a splay tree | |
| (<classname>tree</classname> | |
| with <classname>Tag =</classname> <classname>splay_tree_tag</classname> ) can | |
| be higher than logarithmic; the longest path of a red-black | |
| tree (<classname>tree</classname> | |
| with <classname>Tag =</classname> <classname>rb_tree_tag</classname> ) is | |
| logarithmic in the number of elements. Consequently, the splay | |
| tree has worse performance than the red-black tree.</para> | |
| </section> | |
| </section> | |
| </section> <!-- branch --> | |
| <section xml:id="performance.multimap"> | |
| <info><title>Multimap</title></info> | |
| <para></para> | |
| <!-- 01 <a href="multimap_text_find_timing_test_small"> --> | |
| <section xml:id="performance.multimap.text_find_small"> | |
| <info><title> | |
| Text <function>find</function> with Small Secondary-to-Primary Key Ratios | |
| </title></info> | |
| <para></para> | |
| <section xml:id="multimap.text_find_small.info"> | |
| <info><title> | |
| Description | |
| </title></info> | |
| <para>This test inserts a number of pairs into a container. The | |
| first item of each pair is a string from an arbitrary text | |
| ([wickland96thirty]), and | |
| the second is a uniform i.i.d.integer. The container is a | |
| "multimap" - it considers the first member of each pair as a | |
| primary key, and the second member of each pair as a secondary | |
| key (see Motivation::Associative | |
| Containers::Alternative to Multiple Equivalent Keys). There | |
| are 400 distinct primary keys, and the ratio of secondary keys | |
| to primary keys ranges from 1 to 5.</para> | |
| <para>The test measures the average find-time as a function of the | |
| number of values inserted. For this library's containers, it | |
| finds the secondary key from a container obtained from finding | |
| a primary key. For the native multimaps, it searches a range | |
| obtained using <classname>std::equal_range</classname> on a primary key.</para> | |
| <para> | |
| It uses the test file: | |
| <filename>performance/ext/pb_ds/multimap_text_find_timing_small.cc</filename> | |
| </para> | |
| <para>The test checks the find-time scalability of different | |
| "multimap" designs.</para> | |
| </section> | |
| <section xml:id="multimap.text_find_small.results"> | |
| <info><title> | |
| Results | |
| </title></info> | |
| <para>The graphic below show the results for "multimaps" which | |
| use a tree-based container for primary keys. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_multimap_text_find_small_s2p_tree.png"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="33" | |
| fileref="../images/pbds_multimap_text_find_small_s2p_tree.pdf"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="7" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <colspec colname="c4"/> | |
| <colspec colname="c5"/> | |
| <colspec colname="c6"/> | |
| <colspec colname="c7"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| n_mmap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::multimap</classname> | |
| </entry> | |
| <entry namest="c2" nameend="c7"></entry> | |
| </row> | |
| <!-- multimap 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| rb_tree_mmap_lu_mtf_set | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>tree</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>rb_tree_tag</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Node_Update</classname> | |
| </entry> | |
| <entry> | |
| <classname>null_node_update</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Mapped</classname> | |
| </entry> | |
| <entry> | |
| <classname>list_update</classname> | |
| </entry> | |
| <entry> | |
| <classname>Update_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>lu_move_to_front_policy</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <!-- multimap 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| rb_tree_mmap_cc_hash_mask_exp_1div2_nsth_set | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="4" valign="top"> | |
| <classname>tree</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>rb_tree_tag</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Node_Update</classname> | |
| </entry> | |
| <entry> | |
| <classname>null_node_update</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>Mapped</classname> | |
| </entry> | |
| <entry morerows="2" valign="top"> | |
| <classname>cc_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| <para>The graphic below show the results for "multimaps" which | |
| use a hash-based container for primary keys. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_multimap_text_find_small_s2p_hash.png"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="33" | |
| fileref="../images/pbds_multimap_text_find_small_s2p_hash.pdf"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="7" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <colspec colname="c4"/> | |
| <colspec colname="c5"/> | |
| <colspec colname="c6"/> | |
| <colspec colname="c7"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| n_hash_mmap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::tr1::unordered_multimap</classname> | |
| </entry> | |
| <entry namest="c2" nameend="c7"></entry> | |
| </row> | |
| <!-- multimap 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| rb_tree_mmap_lu_mtf_set | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="3" valign="top"> | |
| <classname> | |
| cc_hash_table | |
| </classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Mapped</classname> | |
| </entry> | |
| <entry> | |
| <classname>list_update</classname> | |
| </entry> | |
| <entry> | |
| <classname>Update_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>lu_move_to_front_policy</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <!-- multimap 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| rb_tree_mmap_cc_hash_mask_exp_1div2_nsth_set | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="5" valign="top"> | |
| <classname> | |
| cc_hash_table | |
| </classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>Mapped</classname> | |
| </entry> | |
| <entry morerows="2" valign="top"> | |
| <classname>cc_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| </section> | |
| <section xml:id="multimap.text_find_small.observations"> | |
| <info><title> | |
| Observations | |
| </title></info> | |
| <para>See Observations::Mapping-Semantics | |
| Considerations.</para> | |
| </section> | |
| </section> | |
| <!-- 02 <a href="multimap_text_find_timing_test_large"> --> | |
| <section xml:id="performance.multimap.text_find_large"> | |
| <info><title> | |
| Text <function>find</function> with Large Secondary-to-Primary Key Ratios | |
| </title></info> | |
| <para></para> | |
| <section xml:id="multimap.text_find_large.info"> | |
| <info><title> | |
| Description | |
| </title></info> | |
| <para>This test inserts a number of pairs into a container. The | |
| first item of each pair is a string from an arbitrary text | |
| ([wickland96thirty]), and | |
| the second is a uniform integer. The container is a | |
| "multimap" - it considers the first member of each pair as a | |
| primary key, and the second member of each pair as a secondary | |
| key. There | |
| are 400 distinct primary keys, and the ratio of secondary keys | |
| to primary keys ranges from 1 to 5.</para> | |
| <para>The test measures the average find-time as a function of the | |
| number of values inserted. For this library's containers, it | |
| finds the secondary key from a container obtained from finding | |
| a primary key. For the native multimaps, it searches a range | |
| obtained using <classname>std::equal_range</classname> on a primary key.</para> | |
| <para> | |
| It uses the test file: | |
| <filename>performance/ext/pb_ds/multimap_text_find_timing_large.cc</filename> | |
| </para> | |
| <para>The test checks the find-time scalability of different | |
| "multimap" designs.</para> | |
| </section> | |
| <section xml:id="multimap.text_find_large.results"> | |
| <info><title> | |
| Results | |
| </title></info> | |
| <para>The graphic below show the results for "multimaps" which | |
| use a tree-based container for primary keys. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_multimap_text_find_large_s2p_tree.png"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="33" | |
| fileref="../images/pbds_multimap_text_find_large_s2p_tree.pdf"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="7" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <colspec colname="c4"/> | |
| <colspec colname="c5"/> | |
| <colspec colname="c6"/> | |
| <colspec colname="c7"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| n_mmap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::multimap</classname> | |
| </entry> | |
| <entry namest="c2" nameend="c7"></entry> | |
| </row> | |
| <!-- multimap 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| rb_tree_mmap_lu_mtf_set | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>tree</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>rb_tree_tag</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Node_Update</classname> | |
| </entry> | |
| <entry> | |
| <classname>null_node_update</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Mapped</classname> | |
| </entry> | |
| <entry> | |
| <classname>list_update</classname> | |
| </entry> | |
| <entry> | |
| <classname>Update_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>lu_move_to_front_policy</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <!-- multimap 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| rb_tree_mmap_cc_hash_mask_exp_1div2_nsth_set | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="4" valign="top"> | |
| <classname>tree</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>rb_tree_tag</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Node_Update</classname> | |
| </entry> | |
| <entry> | |
| <classname>null_node_update</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>Mapped</classname> | |
| </entry> | |
| <entry morerows="2" valign="top"> | |
| <classname>cc_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| <para>The graphic below show the results for "multimaps" which | |
| use a hash-based container for primary keys. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_multimap_text_find_large_s2p_hash.png"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="33" | |
| fileref="../images/pbds_multimap_text_find_large_s2p_hash.pdf"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="7" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <colspec colname="c4"/> | |
| <colspec colname="c5"/> | |
| <colspec colname="c6"/> | |
| <colspec colname="c7"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| n_hash_mmap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::tr1::unordered_multimap</classname> | |
| </entry> | |
| <entry namest="c2" nameend="c7"></entry> | |
| </row> | |
| <!-- multimap 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| rb_tree_mmap_lu_mtf_set | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="3" valign="top"> | |
| <classname> | |
| cc_hash_table | |
| </classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Mapped</classname> | |
| </entry> | |
| <entry> | |
| <classname>list_update</classname> | |
| </entry> | |
| <entry> | |
| <classname>Update_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>lu_move_to_front_policy</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <!-- multimap 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| rb_tree_mmap_cc_hash_mask_exp_1div2_nsth_set | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="5" valign="top"> | |
| <classname> | |
| cc_hash_table | |
| </classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>Mapped</classname> | |
| </entry> | |
| <entry morerows="2" valign="top"> | |
| <classname>cc_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| </section> | |
| <section xml:id="multimap.text_find_large.observations"> | |
| <info><title> | |
| Observations | |
| </title></info> | |
| <para>See Observations::Mapping-Semantics | |
| Considerations.</para> | |
| </section> | |
| </section> | |
| <!-- 03 <a href="multimap_text_insert_timing_test_small"> --> | |
| <section xml:id="performance.multimap.text_insert_small"> | |
| <info><title> | |
| Text <function>insert</function> with Small | |
| Secondary-to-Primary Key Ratios | |
| </title></info> | |
| <para></para> | |
| <section xml:id="multimap.text_insert_small.info"> | |
| <info><title> | |
| Description | |
| </title></info> | |
| <para>This test inserts a number of pairs into a container. The | |
| first item of each pair is a string from an arbitrary text | |
| ([wickland96thirty]), and | |
| the second is a uniform integer. The container is a | |
| "multimap" - it considers the first member of each pair as a | |
| primary key, and the second member of each pair as a secondary | |
| key. There | |
| are 400 distinct primary keys, and the ratio of secondary keys | |
| to primary keys ranges from 1 to 5.</para> | |
| <para>The test measures the average insert-time as a function of | |
| the number of values inserted. For this library's containers, | |
| it inserts a primary key into the primary associative | |
| container, then a secondary key into the secondary associative | |
| container. For the native multimaps, it obtains a range using | |
| <classname>std::equal_range</classname>, and inserts a value only if it was | |
| not contained already.</para> | |
| <para> | |
| It uses the test file: | |
| <filename>performance/ext/pb_ds/multimap_text_insert_timing_small.cc</filename> | |
| </para> | |
| <para>The test checks the insert-time scalability of different | |
| "multimap" designs.</para> | |
| </section> | |
| <section xml:id="multimap.text_insert_small.results"> | |
| <info><title> | |
| Results | |
| </title></info> | |
| <para>The graphic below show the results for "multimaps" which | |
| use a tree-based container for primary keys. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_multimap_text_insert_small_s2p_tree.png"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="33" | |
| fileref="../images/pbds_multimap_text_insert_small_s2p_tree.pdf"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="7" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <colspec colname="c4"/> | |
| <colspec colname="c5"/> | |
| <colspec colname="c6"/> | |
| <colspec colname="c7"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| n_mmap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::multimap</classname> | |
| </entry> | |
| <entry namest="c2" nameend="c7"></entry> | |
| </row> | |
| <!-- multimap 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| rb_tree_mmap_lu_mtf_set | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>tree</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>rb_tree_tag</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Node_Update</classname> | |
| </entry> | |
| <entry> | |
| <classname>null_node_update</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Mapped</classname> | |
| </entry> | |
| <entry> | |
| <classname>list_update</classname> | |
| </entry> | |
| <entry> | |
| <classname>Update_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>lu_move_to_front_policy</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <!-- multimap 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| rb_tree_mmap_cc_hash_mask_exp_1div2_nsth_set | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="4" valign="top"> | |
| <classname>tree</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>rb_tree_tag</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Node_Update</classname> | |
| </entry> | |
| <entry> | |
| <classname>null_node_update</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>Mapped</classname> | |
| </entry> | |
| <entry morerows="2" valign="top"> | |
| <classname>cc_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| <para>The graphic below show the results for "multimaps" which | |
| use a hash-based container for primary keys. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_multimap_text_find_small_s2p_hash.png"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="33" | |
| fileref="../images/pbds_multimap_text_find_small_s2p_hash.pdf"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="7" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <colspec colname="c4"/> | |
| <colspec colname="c5"/> | |
| <colspec colname="c6"/> | |
| <colspec colname="c7"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| n_hash_mmap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::tr1::unordered_multimap</classname> | |
| </entry> | |
| <entry namest="c2" nameend="c7"></entry> | |
| </row> | |
| <!-- multimap 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| rb_tree_mmap_lu_mtf_set | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="3" valign="top"> | |
| <classname> | |
| cc_hash_table | |
| </classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Mapped</classname> | |
| </entry> | |
| <entry> | |
| <classname>list_update</classname> | |
| </entry> | |
| <entry> | |
| <classname>Update_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>lu_move_to_front_policy</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <!-- multimap 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| rb_tree_mmap_cc_hash_mask_exp_1div2_nsth_set | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="5" valign="top"> | |
| <classname> | |
| cc_hash_table | |
| </classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>Mapped</classname> | |
| </entry> | |
| <entry morerows="2" valign="top"> | |
| <classname>cc_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| </section> | |
| <section xml:id="multimap.text_insert_small.observations"> | |
| <info><title> | |
| Observations | |
| </title></info> | |
| <para>See Observations::Mapping-Semantics | |
| Considerations.</para> | |
| </section> | |
| </section> | |
| <!-- 04 <a href="multimap_text_insert_timing_test_large"> --> | |
| <section xml:id="performance.multimap.text_insert_large"> | |
| <info><title> | |
| Text <function>insert</function> with Small | |
| Secondary-to-Primary Key Ratios | |
| </title></info> | |
| <para></para> | |
| <section xml:id="multimap.text_insert_large.info"> | |
| <info><title> | |
| Description | |
| </title></info> | |
| <para>This test inserts a number of pairs into a container. The | |
| first item of each pair is a string from an arbitrary text | |
| ([wickland96thirty]), and | |
| the second is a uniform integer. The container is a | |
| "multimap" - it considers the first member of each pair as a | |
| primary key, and the second member of each pair as a secondary | |
| key. There | |
| are 400 distinct primary keys, and the ratio of secondary keys | |
| to primary keys ranges from 1 to 5.</para> | |
| <para>The test measures the average insert-time as a function of | |
| the number of values inserted. For this library's containers, | |
| it inserts a primary key into the primary associative | |
| container, then a secondary key into the secondary associative | |
| container. For the native multimaps, it obtains a range using | |
| <classname>std::equal_range</classname>, and inserts a value only if it was | |
| not contained already.</para> | |
| <para> | |
| It uses the test file: | |
| <filename>performance/ext/pb_ds/multimap_text_insert_timing_large.cc</filename> | |
| </para> | |
| <para>The test checks the insert-time scalability of different | |
| "multimap" designs.</para> | |
| </section> | |
| <section xml:id="multimap.text_insert_large.results"> | |
| <info><title> | |
| Results | |
| </title></info> | |
| <para>The graphic below show the results for "multimaps" which | |
| use a tree-based container for primary keys. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_multimap_text_insert_large_s2p_tree.png"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="33" | |
| fileref="../images/pbds_multimap_text_insert_large_s2p_tree.pdf"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="7" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <colspec colname="c4"/> | |
| <colspec colname="c5"/> | |
| <colspec colname="c6"/> | |
| <colspec colname="c7"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| n_mmap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::multimap</classname> | |
| </entry> | |
| <entry namest="c2" nameend="c7"></entry> | |
| </row> | |
| <!-- multimap 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| rb_tree_mmap_lu_mtf_set | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>tree</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>rb_tree_tag</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Node_Update</classname> | |
| </entry> | |
| <entry> | |
| <classname>null_node_update</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Mapped</classname> | |
| </entry> | |
| <entry> | |
| <classname>list_update</classname> | |
| </entry> | |
| <entry> | |
| <classname>Update_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>lu_move_to_front_policy</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <!-- multimap 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| rb_tree_mmap_cc_hash_mask_exp_1div2_nsth_set | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="4" valign="top"> | |
| <classname>tree</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>rb_tree_tag</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Node_Update</classname> | |
| </entry> | |
| <entry> | |
| <classname>null_node_update</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>Mapped</classname> | |
| </entry> | |
| <entry morerows="2" valign="top"> | |
| <classname>cc_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| <para>The graphic below show the results for "multimaps" which | |
| use a hash-based container for primary keys. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_multimap_text_find_large_s2p_hash.png"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="33" | |
| fileref="../images/pbds_multimap_text_find_large_s2p_hash.pdf"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="7" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <colspec colname="c4"/> | |
| <colspec colname="c5"/> | |
| <colspec colname="c6"/> | |
| <colspec colname="c7"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| n_hash_mmap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::tr1::unordered_multimap</classname> | |
| </entry> | |
| <entry namest="c2" nameend="c7"></entry> | |
| </row> | |
| <!-- multimap 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| rb_tree_mmap_lu_mtf_set | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="3" valign="top"> | |
| <classname> | |
| cc_hash_table | |
| </classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Mapped</classname> | |
| </entry> | |
| <entry> | |
| <classname>list_update</classname> | |
| </entry> | |
| <entry> | |
| <classname>Update_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>lu_move_to_front_policy</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <!-- multimap 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| rb_tree_mmap_cc_hash_mask_exp_1div2_nsth_set | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="5" valign="top"> | |
| <classname> | |
| cc_hash_table | |
| </classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>Mapped</classname> | |
| </entry> | |
| <entry morerows="2" valign="top"> | |
| <classname>cc_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| </section> | |
| <section xml:id="multimap.text_insert_large.observations"> | |
| <info><title> | |
| Observations | |
| </title></info> | |
| <para>See Observations::Mapping-Semantics | |
| Considerations.</para> | |
| </section> | |
| </section> | |
| <!-- 05 <a href="multimap_text_insert_mem_usage_test_small"> --> | |
| <section xml:id="performance.multimap.text_insert_mem_small"> | |
| <info><title> | |
| Text <function>insert</function> with Small | |
| Secondary-to-Primary Key Ratios Memory Use | |
| </title></info> | |
| <para></para> | |
| <section xml:id="multimap.text_insert_mem_small.info"> | |
| <info><title> | |
| Description | |
| </title></info> | |
| <para>This test inserts a number of pairs into a container. The | |
| first item of each pair is a string from an arbitrary text | |
| ([wickland96thirty]), and | |
| the second is a uniform integer. The container is a | |
| "multimap" - it considers the first member of each pair as a | |
| primary key, and the second member of each pair as a secondary | |
| key. There | |
| are 100 distinct primary keys, and the ratio of secondary keys | |
| to primary keys ranges to about 20.</para> | |
| <para>The test measures the memory use as a function of the number | |
| of values inserted.</para> | |
| <para> | |
| It uses the test file: | |
| <filename>performance/ext/pb_ds/multimap_text_insert_mem_usage_small.cc</filename> | |
| </para> | |
| <para>The test checks the memory scalability of different | |
| "multimap" designs.</para> | |
| </section> | |
| <section xml:id="multimap.text_insert_mem_small.results"> | |
| <info><title> | |
| Results | |
| </title></info> | |
| <para>The graphic below show the results for "multimaps" which | |
| use a tree-based container for primary keys. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_multimap_text_insert_mem_small_s2p_tree.png"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="33" | |
| fileref="../images/pbds_multimap_text_insert_mem_small_s2p_tree.pdf"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="7" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <colspec colname="c4"/> | |
| <colspec colname="c5"/> | |
| <colspec colname="c6"/> | |
| <colspec colname="c7"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| n_mmap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::multimap</classname> | |
| </entry> | |
| <entry namest="c2" nameend="c7"></entry> | |
| </row> | |
| <!-- multimap 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| rb_tree_mmap_lu_mtf_set | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>tree</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>rb_tree_tag</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Node_Update</classname> | |
| </entry> | |
| <entry> | |
| <classname>null_node_update</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Mapped</classname> | |
| </entry> | |
| <entry> | |
| <classname>list_update</classname> | |
| </entry> | |
| <entry> | |
| <classname>Update_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>lu_move_to_front_policy</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <!-- multimap 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| rb_tree_mmap_cc_hash_mask_exp_1div2_nsth_set | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="4" valign="top"> | |
| <classname>tree</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>rb_tree_tag</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Node_Update</classname> | |
| </entry> | |
| <entry> | |
| <classname>null_node_update</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>Mapped</classname> | |
| </entry> | |
| <entry morerows="2" valign="top"> | |
| <classname>cc_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| <para>The graphic below show the results for "multimaps" which | |
| use a hash-based container for primary keys. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_multimap_text_find_large_s2p_hash.png"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="33" | |
| fileref="../images/pbds_multimap_text_find_large_s2p_hash.pdf"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="7" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <colspec colname="c4"/> | |
| <colspec colname="c5"/> | |
| <colspec colname="c6"/> | |
| <colspec colname="c7"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| n_hash_mmap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::tr1::unordered_multimap</classname> | |
| </entry> | |
| <entry namest="c2" nameend="c7"></entry> | |
| </row> | |
| <!-- multimap 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| rb_tree_mmap_lu_mtf_set | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="3" valign="top"> | |
| <classname> | |
| cc_hash_table | |
| </classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Mapped</classname> | |
| </entry> | |
| <entry> | |
| <classname>list_update</classname> | |
| </entry> | |
| <entry> | |
| <classname>Update_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>lu_move_to_front_policy</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <!-- multimap 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| rb_tree_mmap_cc_hash_mask_exp_1div2_nsth_set | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="5" valign="top"> | |
| <classname> | |
| cc_hash_table | |
| </classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>Mapped</classname> | |
| </entry> | |
| <entry morerows="2" valign="top"> | |
| <classname>cc_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| </section> | |
| <section xml:id="multimap.text_insert_mem_small.observations"> | |
| <info><title> | |
| Observations | |
| </title></info> | |
| <para>See Observations::Mapping-Semantics | |
| Considerations.</para> | |
| </section> | |
| </section> | |
| <!-- 06 <a href="multimap_text_insert_mem_usage_test_large"> --> | |
| <section xml:id="performance.multimap.text_insert_mem_large"> | |
| <info><title> | |
| Text <function>insert</function> with Small | |
| Secondary-to-Primary Key Ratios Memory Use | |
| </title></info> | |
| <para></para> | |
| <section xml:id="multimap.text_insert_mem_large.info"> | |
| <info><title> | |
| Description | |
| </title></info> | |
| <para>This test inserts a number of pairs into a container. The | |
| first item of each pair is a string from an arbitrary text | |
| ([wickland96thirty]), and | |
| the second is a uniform integer. The container is a | |
| "multimap" - it considers the first member of each pair as a | |
| primary key, and the second member of each pair as a secondary | |
| key. There | |
| are 100 distinct primary keys, and the ratio of secondary keys | |
| to primary keys ranges to about 20.</para> | |
| <para>The test measures the memory use as a function of the number | |
| of values inserted.</para> | |
| <para> | |
| It uses the test file: | |
| <filename>performance/ext/pb_ds/multimap_text_insert_mem_usage_large.cc</filename> | |
| </para> | |
| <para>The test checks the memory scalability of different | |
| "multimap" designs.</para> | |
| </section> | |
| <section xml:id="multimap.text_insert_mem_large.results"> | |
| <info><title> | |
| Results | |
| </title></info> | |
| <para>The graphic below show the results for "multimaps" which | |
| use a tree-based container for primary keys. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_multimap_text_insert_mem_large_s2p_tree.png"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="33" | |
| fileref="../images/pbds_multimap_text_insert_mem_large_s2p_tree.pdf"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="7" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <colspec colname="c4"/> | |
| <colspec colname="c5"/> | |
| <colspec colname="c6"/> | |
| <colspec colname="c7"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| n_mmap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::multimap</classname> | |
| </entry> | |
| <entry namest="c2" nameend="c7"></entry> | |
| </row> | |
| <!-- multimap 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| rb_tree_mmap_lu_mtf_set | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>tree</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>rb_tree_tag</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Node_Update</classname> | |
| </entry> | |
| <entry> | |
| <classname>null_node_update</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Mapped</classname> | |
| </entry> | |
| <entry> | |
| <classname>list_update</classname> | |
| </entry> | |
| <entry> | |
| <classname>Update_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>lu_move_to_front_policy</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <!-- multimap 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| rb_tree_mmap_cc_hash_mask_exp_1div2_nsth_set | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="4" valign="top"> | |
| <classname>tree</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>rb_tree_tag</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Node_Update</classname> | |
| </entry> | |
| <entry> | |
| <classname>null_node_update</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>Mapped</classname> | |
| </entry> | |
| <entry morerows="2" valign="top"> | |
| <classname>cc_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| <para>The graphic below show the results for "multimaps" which | |
| use a hash-based container for primary keys. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_multimap_text_find_large_s2p_hash.png"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="33" | |
| fileref="../images/pbds_multimap_text_find_large_s2p_hash.pdf"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="7" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <colspec colname="c4"/> | |
| <colspec colname="c5"/> | |
| <colspec colname="c6"/> | |
| <colspec colname="c7"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| n_hash_mmap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::tr1::unordered_multimap</classname> | |
| </entry> | |
| <entry namest="c2" nameend="c7"></entry> | |
| </row> | |
| <!-- multimap 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| rb_tree_mmap_lu_mtf_set | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="3" valign="top"> | |
| <classname> | |
| cc_hash_table | |
| </classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>Mapped</classname> | |
| </entry> | |
| <entry> | |
| <classname>list_update</classname> | |
| </entry> | |
| <entry> | |
| <classname>Update_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>lu_move_to_front_policy</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <!-- multimap 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c7"> | |
| rb_tree_mmap_cc_hash_mask_exp_1div2_nsth_set | |
| </entry> | |
| </row> | |
| <row> | |
| <entry morerows="5" valign="top"> | |
| <classname> | |
| cc_hash_table | |
| </classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c4" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="2" valign="top"> | |
| <classname>Mapped</classname> | |
| </entry> | |
| <entry morerows="2" valign="top"> | |
| <classname>cc_hash_table</classname> | |
| </entry> | |
| <entry> | |
| <classname>Comb_Hash_Fn</classname> | |
| </entry> | |
| <entry> | |
| <classname>direct_mask_range_hashing</classname> | |
| </entry> | |
| <entry namest="c6" nameend="c7"></entry> | |
| </row> | |
| <row> | |
| <entry morerows="1" valign="top"> | |
| <classname>Resize_Policy</classname> | |
| </entry> | |
| <entry morerows="1" valign="top"> | |
| <classname>hash_standard_resize_policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>Size_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_exponential_size_policy</classname> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry valign="top"> | |
| <classname>Trigger_Policy</classname> | |
| </entry> | |
| <entry> | |
| <classname>hash_load_check_resize_trigger</classname> with | |
| α<subscript>min</subscript> = 1/8 and α<subscript>max</subscript> = 1/2 | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| </section> | |
| <section xml:id="multimap.text_insert_mem_large.observations"> | |
| <info><title> | |
| Observations | |
| </title></info> | |
| <para>See Observations::Mapping-Semantics | |
| Considerations.</para> | |
| </section> | |
| </section> | |
| </section> <!-- multimap --> | |
| <section xml:id="performance.priority_queue"> | |
| <info><title>Priority Queue</title></info> | |
| <!-- 01 <a href="priority_queue_text_push_timing_test"> --> | |
| <section xml:id="performance.priority_queue.text_push"> | |
| <info><title> | |
| Text <function>push</function> | |
| </title></info> | |
| <para></para> | |
| <section xml:id="priority_queue.text_push.info"> | |
| <info><title> | |
| Description | |
| </title></info> | |
| <para>This test inserts a number of values with keys from an | |
| arbitrary text ([ wickland96thirty ]) into | |
| a container using <function>push</function>. It measures the average time | |
| for <function>push</function> as a function of the number of values | |
| pushed.</para> | |
| <para> | |
| It uses the test file: | |
| <filename>performance/ext/pb_ds/priority_queue_text_push_timing.cc</filename> | |
| </para> | |
| <para>The test checks the effect of different underlying data | |
| structures. | |
| </para> | |
| </section> | |
| <section xml:id="priority_queue.text_push.results"> | |
| <info><title> | |
| Results | |
| </title></info> | |
| <para>The two graphics below show the results for the native | |
| priority_queues and this library's priority_queues. | |
| </para> | |
| <para>The graphic immediately below shows the results for the | |
| native priority_queue type instantiated with different underlying | |
| container types versus several different versions of library's | |
| priority_queues. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="75" | |
| fileref="../images/pbds_priority_queue_text_push.pdf"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_priority_queue_text_push.png"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="3" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| n_pq_vector | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Sequence</classname> | |
| </entry> | |
| <entry> | |
| <classname>std::vector</classname> | |
| </entry> | |
| </row> | |
| <!-- native 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| n_pq_deque | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Sequence</classname> | |
| </entry> | |
| <entry> | |
| <classname>std::deque</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| binary_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>binary_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| binomial_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>binomial_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 03 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| rc_binomial_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>rc_binomial_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 04 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| thin_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>thin_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 05 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| pairing_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>pairing_heap_tag</classname> | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| <para>The graphic below shows the results for the binary-heap | |
| based native priority queues and this library's pairing-heap | |
| priority_queue data structures. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="75" | |
| fileref="../images/pbds_pairing_priority_queue_text_push.pdf"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_pairing_priority_queue_text_push.png"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="3" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| n_pq_vector | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Sequence</classname> | |
| </entry> | |
| <entry> | |
| <classname>std::vector</classname> | |
| </entry> | |
| </row> | |
| <!-- native 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| n_pq_deque | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Sequence</classname> | |
| </entry> | |
| <entry> | |
| <classname>std::deque</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| thin_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>thin_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| pairing_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>pairing_heap_tag</classname> | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| </section> | |
| <section xml:id="priority_queue.text_push.observations"> | |
| <info><title> | |
| Observations | |
| </title></info> | |
| <para>Pairing heaps (<classname>priority_queue</classname> with | |
| <classname>Tag</classname> = <classname>pairing_heap_tag</classname>) | |
| are the most suited for sequences of <function>push</function> and | |
| <function>pop</function> operations of non-primitive types (e.g. | |
| <classname>std::string</classname>s). (See Priority Queue | |
| Text <function>push</function> and <function>pop</function> Timing Test.) They are | |
| less constrained than binomial heaps, e.g., and since | |
| they are node-based, they outperform binary heaps. (See | |
| Priority | |
| Queue Random Integer <function>push</function> Timing Test for the case | |
| of primitive types.)</para> | |
| <para>The standard's priority queues do not seem to perform well in | |
| this case: the <classname>std::vector</classname> implementation needs to | |
| perform a logarithmic sequence of string operations for each | |
| operation, and the deque implementation is possibly hampered by | |
| its need to manipulate a relatively-complex type (deques | |
| support a O(1) <function>push_front</function>, even though it is | |
| not used by <classname>std::priority_queue</classname>.)</para> | |
| </section> | |
| </section> | |
| <!-- 02 <a href="priority_queue_text_push_pop_timing_test"> --> | |
| <section xml:id="performance.priority_queue.text_push_pop"> | |
| <info><title> | |
| Text <function>push</function> and <function>pop</function> | |
| </title></info> | |
| <para></para> | |
| <section xml:id="priority_queue.text_push_pop.info"> | |
| <info><title> | |
| Description | |
| </title></info> | |
| <para>This test inserts a number of values with keys from an | |
| arbitrary text ([ wickland96thirty ]) into | |
| a container using <classname>push</classname> , then removes them using | |
| <classname>pop</classname> . It measures the average time for <classname>push</classname> | |
| as a function of the number of values.</para> | |
| <para> | |
| It uses the test file: | |
| <filename>performance/ext/pb_ds/priority_queue_text_push_pop_timing.cc</filename> | |
| </para> | |
| <para>The test checks the effect of different underlying data | |
| structures. | |
| </para> | |
| </section> | |
| <section xml:id="priority_queue.text_push_pop.results"> | |
| <info><title> | |
| Results | |
| </title></info> | |
| <para>The two graphics below show the results for the native | |
| priority_queues and this library's priority_queues. | |
| </para> | |
| <para>The graphic immediately below shows the results for the | |
| native priority_queue type instantiated with different underlying | |
| container types versus several different versions of library's | |
| priority_queues. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="75" | |
| fileref="../images/pbds_priority_queue_text_push_pop.pdf"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_priority_queue_text_push_pop.png"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="3" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| n_pq_vector | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Sequence</classname> | |
| </entry> | |
| <entry> | |
| <classname>std::vector</classname> | |
| </entry> | |
| </row> | |
| <!-- native 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| n_pq_deque | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Sequence</classname> | |
| </entry> | |
| <entry> | |
| <classname>std::deque</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| binary_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>binary_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| binomial_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>binomial_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 03 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| rc_binomial_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>rc_binomial_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 04 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| thin_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>thin_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 05 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| pairing_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>pairing_heap_tag</classname> | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| <para>The graphic below shows the results for the native priority | |
| queues and this library's pairing-heap priority_queue data | |
| structures. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="75" | |
| fileref="../images/pbds_pairing_priority_queue_text_push_pop.pdf"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_pairing_priority_queue_text_push_pop.png"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="3" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| n_pq_vector | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::priority_queue</classname> adapting <classname>std::vector</classname> | |
| </entry> | |
| <entry> | |
| <classname>Sequence</classname> | |
| </entry> | |
| <entry> | |
| <classname>std::vector</classname> | |
| </entry> | |
| </row> | |
| <!-- native 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| n_pq_deque | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Sequence</classname> | |
| </entry> | |
| <entry> | |
| <classname>std::deque</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| pairing_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>pairing_heap_tag</classname> | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| </section> | |
| <section xml:id="priority_queue.text_push_pop.observations"> | |
| <info><title> | |
| Observations | |
| </title></info> | |
| <para>These results are very similar to Priority Queue Text | |
| <function>push</function> Timing Test. As stated there, pairing heaps | |
| (<classname>priority_queue</classname> with | |
| <classname>Tag</classname> | |
| = <classname>pairing_heap_tag</classname>) are most suited | |
| for <function>push</function> and <function>pop</function> | |
| sequences of non-primitive types such as strings. Observing these | |
| two tests, one can note that a pairing heap outperforms the others | |
| in terms of <function>push</function> operations, but equals | |
| binary heaps (<classname>priority_queue</classname> with | |
| <classname>Tag</classname> | |
| = <classname>binary_heap_tag</classname>) if the number | |
| of <function>push</function> and <function>pop</function> | |
| operations is equal. As the number of <function>pop</function> | |
| operations is at most equal to the number | |
| of <function>push</function> operations, pairing heaps are better | |
| in this case. See Priority Queue Random | |
| Integer <function>push</function> and <function>pop</function> | |
| Timing Test for a case which is different.</para> | |
| </section> | |
| </section> | |
| <!-- 03 <a href="priority_queue_random_int_push_timing_test"> --> | |
| <section xml:id="performance.priority_queue.int_push"> | |
| <info><title> | |
| Integer <function>push</function> | |
| </title></info> | |
| <para></para> | |
| <section xml:id="priority_queue.int_push.info"> | |
| <info><title> | |
| Description | |
| </title></info> | |
| <para>This test inserts a number of values with integer keys | |
| into a container using <function>push</function>. It | |
| measures the average time for <function>push</function> as a | |
| function of the number of values.</para> | |
| <para> | |
| It uses the test file: | |
| <filename>performance/ext/pb_ds/priority_queue_random_int_push_timing.cc</filename> | |
| </para> | |
| <para>The test checks the effect of different underlying data | |
| structures. | |
| </para> | |
| </section> | |
| <section xml:id="priority_queue.int_push.results"> | |
| <info><title> | |
| Results | |
| </title></info> | |
| <para>The two graphics below show the results for the native | |
| priority_queues and this library's priority_queues. | |
| </para> | |
| <para>The graphic immediately below shows the results for the | |
| native priority_queue type instantiated with different underlying | |
| container types versus several different versions of library's | |
| priority_queues. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="75" | |
| fileref="../images/pbds_priority_queue_int_push.pdf"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_priority_queue_int_push.png"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="3" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| n_pq_vector | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Sequence</classname> | |
| </entry> | |
| <entry> | |
| <classname>std::vector</classname> | |
| </entry> | |
| </row> | |
| <!-- native 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| n_pq_deque | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Sequence</classname> | |
| </entry> | |
| <entry> | |
| <classname>std::deque</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| binary_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>binary_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| binomial_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>binomial_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 03 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| rc_binomial_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>rc_binomial_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 04 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| thin_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>thin_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 05 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| pairing_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>pairing_heap_tag</classname> | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| <para>The graphic below shows the results for the binary-heap | |
| based native priority queues and this library's | |
| priority_queue data structures. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="75" | |
| fileref="../images/pbds_binary_priority_queue_int_push.pdf"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_binary_priority_queue_int_push.png"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="3" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| n_pq_vector | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::priority_queue</classname> adapting <classname>std::vector</classname> | |
| </entry> | |
| <entry> | |
| <classname>Sequence</classname> | |
| </entry> | |
| <entry> | |
| <classname>std::vector</classname> | |
| </entry> | |
| </row> | |
| <!-- native 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| n_pq_deque | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Sequence</classname> | |
| </entry> | |
| <entry> | |
| <classname>std::deque</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| binary_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>binary_heap_tag</classname> | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| </section> | |
| <section xml:id="priority_queue.int_push.observations"> | |
| <info><title> | |
| Observations | |
| </title></info> | |
| <para>Binary heaps are the most suited for sequences of | |
| <function>push</function> and <function>pop</function> operations of primitive types | |
| (e.g. <type>int</type>s). They are less constrained | |
| than any other type, and since it is very efficient to store | |
| such types in arrays, they outperform even pairing heaps. (See | |
| Priority | |
| Queue Text <function>push</function> Timing Test for the case of | |
| non-primitive types.)</para> | |
| </section> | |
| </section> | |
| <!-- 04 "priority_queue_random_int_push_pop_timing_test" --> | |
| <section xml:id="performance.priority_queue.int_push_pop"> | |
| <info><title> | |
| Integer <function>push</function> | |
| </title></info> | |
| <para></para> | |
| <section xml:id="priority_queue.int_push_pop.info"> | |
| <info><title> | |
| Description | |
| </title></info> | |
| <para>This test inserts a number of values with integer keys | |
| into a container using <function>push</function> , then removes them | |
| using <function>pop</function> . It measures the average time for | |
| <function>push</function> and <function>pop</function> as a function | |
| of the number of values.</para> | |
| <para> | |
| It uses the test file: | |
| <filename>performance/ext/pb_ds/priority_queue_random_int_push_pop_timing.cc</filename> | |
| </para> | |
| <para>The test checks the effect of different underlying data | |
| structures. | |
| </para> | |
| </section> | |
| <section xml:id="priority_queue.int_push_pop.results"> | |
| <info><title> | |
| Results | |
| </title></info> | |
| <para>The graphic immediately below shows the results for the | |
| native priority_queue type instantiated with different underlying | |
| container types versus several different versions of library's | |
| priority_queues. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="75" | |
| fileref="../images/pbds_priority_queue_int_push_pop.pdf"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_priority_queue_int_push_pop.png"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="3" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| n_pq_vector | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Sequence</classname> | |
| </entry> | |
| <entry> | |
| <classname>std::vector</classname> | |
| </entry> | |
| </row> | |
| <!-- native 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| n_pq_deque | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Sequence</classname> | |
| </entry> | |
| <entry> | |
| <classname>std::deque</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| binary_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>binary_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| binomial_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>binomial_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 03 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| rc_binomial_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>rc_binomial_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 04 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| thin_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>thin_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 05 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| pairing_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>pairing_heap_tag</classname> | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| </section> | |
| <section xml:id="priority_queue.int_push_pop.observations"> | |
| <info><title> | |
| Observations | |
| </title></info> | |
| <para>Binary heaps are the most suited for sequences of | |
| <function>push</function> and <function>pop</function> operations of primitive types | |
| (e.g. <type>int</type>s). This is explained in | |
| Priority | |
| Queue Random Int <function>push</function> Timing Test. (See Priority Queue | |
| Text <function>push</function> Timing Test for the case of primitive | |
| types.)</para> | |
| <para>At first glance it seems that the standard's vector-based | |
| priority queue is approximately on par with this | |
| library's corresponding priority queue. There are two | |
| differences however:</para> | |
| <orderedlist> | |
| <listitem><para>The standard's priority queue does not downsize the underlying | |
| vector (or deque) as the priority queue becomes smaller | |
| (see Priority Queue | |
| Text <function>pop</function> Memory Use Test). It is therefore | |
| gaining some speed at the expense of space.</para></listitem> | |
| <listitem><para>From Priority Queue Random | |
| Integer <function>push</function> and <function>pop</function> | |
| Timing Test, it seems that the standard's priority queue is | |
| slower in terms of <function>push</function> operations. Since | |
| the number of | |
| <function>pop</function> operations is at most that of <function>push</function> | |
| operations, the test here is the "best" for the standard's | |
| priority queue.</para></listitem> | |
| </orderedlist> | |
| </section> | |
| </section> | |
| <!-- 05 <a href="priority_queue_text_pop_mem_usage_test"> --> | |
| <section xml:id="performance.priority_queue.text_pop"> | |
| <info><title> | |
| Text <function>pop</function> Memory Use | |
| </title></info> | |
| <para></para> | |
| <section xml:id="priority_queue.text_pop.info"> | |
| <info><title> | |
| Description | |
| </title></info> | |
| <para>This test inserts a number of values with keys from an | |
| arbitrary text ([ wickland96thirty ]) into | |
| a container, then pops them until only one is left in the | |
| container. It measures the memory use as a function of the | |
| number of values pushed to the container.</para> | |
| <para> | |
| It uses the test file: | |
| <filename>performance/ext/pb_ds/priority_queue_text_pop_mem_usage.cc</filename> | |
| </para> | |
| <para>The test checks the effect of different underlying data | |
| structures. | |
| </para> | |
| </section> | |
| <section xml:id="priority_queue.text_pop.results"> | |
| <info><title> | |
| Results | |
| </title></info> | |
| <para>The graphic immediately below shows the results for the | |
| native priority_queue type instantiated with different underlying | |
| container types versus several different versions of library's | |
| priority_queues. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="75" | |
| fileref="../images/pbds_priority_queue_text_pop_mem.pdf"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_priority_queue_text_pop_mem.png"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="3" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| n_pq_vector | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Sequence</classname> | |
| </entry> | |
| <entry> | |
| <classname>std::vector</classname> | |
| </entry> | |
| </row> | |
| <!-- native 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| n_pq_deque | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Sequence</classname> | |
| </entry> | |
| <entry> | |
| <classname>std::deque</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| binary_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>binary_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| binomial_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>binomial_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 03 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| rc_binomial_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>rc_binomial_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 04 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| thin_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>thin_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 05 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| pairing_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>pairing_heap_tag</classname> | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| </section> | |
| <section xml:id="priority_queue.text_pop.observations"> | |
| <info><title> | |
| Observations | |
| </title></info> | |
| <para>The priority queue implementations (excluding the standard's) use | |
| memory proportionally to the number of values they hold: | |
| node-based implementations (e.g., a pairing heap) do so | |
| naturally; this library's binary heap de-allocates memory when | |
| a certain lower threshold is exceeded.</para> | |
| <para>Note from Priority Queue Text <function>push</function> | |
| and <function>pop</function> Timing Test and Priority Queue | |
| Random Integer <function>push</function> | |
| and <function>pop</function> Timing Test that this does not | |
| impede performance compared to the standard's priority | |
| queues.</para> | |
| <para>See Hash-Based Erase | |
| Memory Use Test for a similar phenomenon regarding priority | |
| queues.</para> | |
| </section> | |
| </section> | |
| <!-- 06 <a href="priority_queue_text_join_timing_test"> --> | |
| <section xml:id="performance.priority_queue.text_join"> | |
| <info><title> | |
| Text <function>join</function> | |
| </title></info> | |
| <para></para> | |
| <section xml:id="priority_queue.text_join.info"> | |
| <info><title> | |
| Description | |
| </title></info> | |
| <para>This test inserts a number of values with keys from an | |
| arbitrary text ([ wickland96thirty ]) into | |
| two containers, then merges the containers. It uses | |
| <function>join</function> for this library's priority queues; for | |
| the standard's priority queues, it successively pops values from | |
| one container and pushes them into the other. The test measures | |
| the average time as a function of the number of values.</para> | |
| <para> | |
| It uses the test file: | |
| <filename>performance/ext/pb_ds/priority_queue_text_join_timing.cc</filename> | |
| </para> | |
| <para>The test checks the effect of different underlying data | |
| structures. | |
| </para> | |
| </section> | |
| <section xml:id="priority_queue.text_join.results"> | |
| <info><title> | |
| Results | |
| </title></info> | |
| <para>The graphic immediately below shows the results for the | |
| native priority_queue type instantiated with different underlying | |
| container types versus several different versions of library's | |
| priority_queues. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="75" | |
| fileref="../images/pbds_priority_queue_text_join.pdf"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_priority_queue_text_join.png"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="3" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| n_pq_vector | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Sequence</classname> | |
| </entry> | |
| <entry> | |
| <classname>std::vector</classname> | |
| </entry> | |
| </row> | |
| <!-- native 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| n_pq_deque | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Sequence</classname> | |
| </entry> | |
| <entry> | |
| <classname>std::deque</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| binary_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>binary_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| binomial_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>binomial_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 03 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| rc_binomial_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>rc_binomial_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 04 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| thin_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>thin_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 05 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| pairing_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>pairing_heap_tag</classname> | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| </section> | |
| <section xml:id="priority_queue.text_join.observations"> | |
| <info><title> | |
| Observations | |
| </title></info> | |
| <para>In this test the node-based heaps perform <function>join</function> in | |
| either logarithmic or constant time. The binary heap requires | |
| linear time, since the well-known heapify algorithm [clrs2001] is linear.</para> | |
| <para>It would be possible to apply the heapify algorithm to the | |
| standard containers, if they would support iteration (which they | |
| don't). Barring iterators, it is still somehow possible to perform | |
| linear-time merge on a <classname>std::vector</classname>-based | |
| standard priority queue, using <function>top()</function> | |
| and <function>size()</function> (since they are enough to expose | |
| the underlying array), but this is impossible for | |
| a <classname>std::deque</classname>-based standard priority queue. | |
| Without heapify, the cost is super-linear.</para> | |
| </section> | |
| </section> | |
| <!-- 07 <a href="priority_queue_text_push_timing_test"> --> | |
| <section xml:id="performance.priority_queue.text_modify_up"> | |
| <info><title> | |
| Text <function>modify</function> Up | |
| </title></info> | |
| <para></para> | |
| <section xml:id="priority_queue.text_modify_up.info"> | |
| <info><title> | |
| Description | |
| </title></info> | |
| <para>This test inserts a number of values with keys from an | |
| arbitrary text ([ wickland96thirty ]) into | |
| into a container then modifies each one "up" (i.e., it | |
| makes it larger). It uses <function>modify</function> for this library's | |
| priority queues; for the standard's priority queues, it pops values | |
| from a container until it reaches the value that should be | |
| modified, then pushes values back in. It measures the average | |
| time for <function>modify</function> as a function of the number of | |
| values.</para> | |
| <para> | |
| It uses the test file: | |
| <filename>performance/ext/pb_ds/priority_queue_text_modify_up_timing.cc</filename> | |
| </para> | |
| <para>The test checks the effect of different underlying data | |
| structures for graph algorithms settings. Note that making an | |
| arbitrary value larger (in the sense of the priority queue's | |
| comparison functor) corresponds to decrease-key in standard graph | |
| algorithms [clrs2001]. | |
| </para> | |
| </section> | |
| <section xml:id="priority_queue.text_modify_up.results"> | |
| <info><title> | |
| Results | |
| </title></info> | |
| <para>The two graphics below show the results for the native | |
| priority_queues and this library's priority_queues. | |
| </para> | |
| <para>The graphic immediately below shows the results for the | |
| native priority_queue type instantiated with different underlying | |
| container types versus several different versions of library's | |
| priority_queues. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="75" | |
| fileref="../images/pbds_priority_queue_text_modify_up.pdf"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_priority_queue_text_modify_up.png"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="3" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| n_pq_vector | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Sequence</classname> | |
| </entry> | |
| <entry> | |
| <classname>std::vector</classname> | |
| </entry> | |
| </row> | |
| <!-- native 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| n_pq_deque | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Sequence</classname> | |
| </entry> | |
| <entry> | |
| <classname>std::deque</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| binary_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>binary_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| binomial_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>binomial_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 03 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| rc_binomial_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>rc_binomial_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 04 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| thin_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>thin_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 05 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| pairing_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>pairing_heap_tag</classname> | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| <para>The graphic below shows the results for the | |
| native priority queues and this library's pairing and thin heap | |
| priority_queue data structures. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="75" | |
| fileref="../images/pbds_pairing_priority_queue_text_modify_up_thin.pdf"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_pairing_priority_queue_text_modify_up_thin.png"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="3" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- priority_queue 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| thin_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>thin_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| pairing_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>pairing_heap_tag</classname> | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| </section> | |
| <section xml:id="priority_queue.text_modify_up.observations"> | |
| <info><title> | |
| Observations | |
| </title></info> | |
| <para>As noted above, increasing an arbitrary value (in the sense of | |
| the priority queue's comparison functor) is very common in | |
| graph-related algorithms. In this case, a thin heap | |
| (<classname>priority_queue</classname> with | |
| <classname>Tag</classname> = <classname>thin_heap_tag</classname>) | |
| outperforms a pairing heap (<classname>priority_queue</classname> with | |
| <classname>Tag</classname> = <classname>pairing_heap_tag</classname>). | |
| Conversely, Priority Queue Text | |
| <function>push</function> Timing Test, Priority Queue | |
| Text <function>push</function> and <function>pop</function> Timing Test, Priority | |
| Queue Random Integer <function>push</function> Timing Test, and | |
| Priority | |
| Queue Random Integer <function>push</function> and <function>pop</function> Timing | |
| Test show that the situation is reversed for other | |
| operations. It is not clear when to prefer one of these two | |
| different types.</para> | |
| <para>In this test this library's binary heaps | |
| effectively perform modify in linear time. As explained in | |
| Priority Queue Design::Traits, given a valid point-type iterator, | |
| a binary heap can perform | |
| <function>modify</function> logarithmically. The problem is that binary | |
| heaps invalidate their find iterators with each modifying | |
| operation, and so the only way to obtain a valid point-type | |
| iterator is to iterate using a range-type iterator until | |
| finding the appropriate value, then use the range-type iterator | |
| for the <function>modify</function> operation.</para> | |
| <para>The explanation for the standard's priority queues' performance | |
| is similar to that in Priority Queue Text | |
| <function>join</function> Timing Test.</para> | |
| </section> | |
| </section> | |
| <!-- 08 <a href="priority_queue_text_modify_down_timing_test"> --> | |
| <section xml:id="performance.priority_queue.text_modify_down"> | |
| <info><title> | |
| Text <function>modify</function> Down | |
| </title></info> | |
| <para></para> | |
| <section xml:id="priority_queue.text_modify_down.info"> | |
| <info><title> | |
| Description | |
| </title></info> | |
| <para>This test inserts a number of values with keys from an | |
| arbitrary text ([ wickland96thirty ]) into | |
| into a container then modifies each one "down" (i.e., it | |
| makes it smaller). It uses <function>modify</function> for this library's | |
| priority queues; for the standard's priority queues, it pops values | |
| from a container until it reaches the value that should be | |
| modified, then pushes values back in. It measures the average | |
| time for <function>modify</function> as a function of the number of | |
| values.</para> | |
| <para> | |
| It uses the test file: | |
| <filename>performance/ext/pb_ds/priority_queue_text_modify_down_timing.cc</filename> | |
| </para> | |
| <para>The main purpose of this test is to contrast Priority Queue | |
| Text <classname>modify</classname> Up Timing Test.</para> | |
| </section> | |
| <section xml:id="priority_queue.text_modify_down.results"> | |
| <info><title> | |
| Results | |
| </title></info> | |
| <para>The two graphics below show the results for the native | |
| priority_queues and this library's priority_queues. | |
| </para> | |
| <para>The graphic immediately below shows the results for the | |
| native priority_queue type instantiated with different underlying | |
| container types versus several different versions of library's | |
| priority_queues. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="75" | |
| fileref="../images/pbds_priority_queue_text_modify_down.pdf"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_priority_queue_text_modify_down.png"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="3" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- native 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| n_pq_vector | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Sequence</classname> | |
| </entry> | |
| <entry> | |
| <classname>std::vector</classname> | |
| </entry> | |
| </row> | |
| <!-- native 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| n_pq_deque | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>std::priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Sequence</classname> | |
| </entry> | |
| <entry> | |
| <classname>std::deque</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| binary_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>binary_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| binomial_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>binomial_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 03 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| rc_binomial_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>rc_binomial_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 04 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| thin_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>thin_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 05 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| pairing_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>pairing_heap_tag</classname> | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| <para>The graphic below shows the results for the | |
| native priority queues and this library's pairing and thin heap | |
| priority_queue data structures. | |
| </para> | |
| <!-- results graphic --> | |
| <informalfigure> | |
| <mediaobject> | |
| <imageobject> | |
| <imagedata align="center" format="PDF" scale="75" | |
| fileref="../images/pbds_pairing_priority_queue_text_modify_down_thin.pdf"/> | |
| </imageobject> | |
| <imageobject> | |
| <imagedata align="center" format="PNG" scale="100" | |
| fileref="../images/pbds_pairing_priority_queue_text_modify_down_thin.png"/> | |
| </imageobject> | |
| </mediaobject> | |
| </informalfigure> | |
| <para> | |
| The abbreviated names in the legend of the graphic above are | |
| instantiated with the types in the following table. | |
| </para> | |
| <informaltable frame="all"> | |
| <tgroup cols="3" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <thead> | |
| <row> | |
| <entry><emphasis>Name/Instantiating Type</emphasis></entry> | |
| <entry><emphasis>Parameter</emphasis></entry> | |
| <entry><emphasis>Details</emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <!-- priority_queue 01 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| thin_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>thin_heap_tag</classname> | |
| </entry> | |
| </row> | |
| <!-- priority_queue 02 --> | |
| <row> | |
| <?dbhtml bgcolor="#B0B0B0" ?> | |
| <entry namest="c1" nameend="c3"> | |
| pairing_heap | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| </entry> | |
| <entry> | |
| <classname>Tag</classname> | |
| </entry> | |
| <entry> | |
| <classname>pairing_heap_tag</classname> | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| </section> | |
| <section xml:id="priority_queue.text_modify_down.observations"> | |
| <info><title> | |
| Observations | |
| </title></info> | |
| <para>Most points in these results are similar to Priority Queue | |
| Text <function>modify</function> Up Timing Test.</para> | |
| <para>It is interesting to note, however, that as opposed to that | |
| test, a thin heap (<classname>priority_queue</classname> with | |
| <classname>Tag</classname> = <classname>thin_heap_tag</classname>) is | |
| outperformed by a pairing heap (<classname>priority_queue</classname> with | |
| <classname>Tag</classname> = <classname>pairing_heap_tag</classname>). | |
| In this case, both heaps essentially perform an <function>erase</function> | |
| operation followed by a <function>push</function> operation. As the other | |
| tests show, a pairing heap is usually far more efficient than a | |
| thin heap, so this is not surprising.</para> | |
| <para>Most algorithms that involve priority queues increase values | |
| (in the sense of the priority queue's comparison functor), and | |
| so Priority Queue | |
| Text <classname>modify</classname> Up Timing Test - is more interesting | |
| than this test.</para> | |
| </section> | |
| </section> | |
| </section> <!-- priority_queue --> | |
| <section xml:id="pbds.test.performance.observations"> | |
| <info><title>Observations</title></info> | |
| <section xml:id="observations.associative"> | |
| <info><title>Associative</title></info> | |
| <section xml:id="observations.associative.underlying"> | |
| <info><title> | |
| Underlying Data-Structure Families | |
| </title></info> | |
| <para>In general, hash-based containers have better timing performance | |
| than containers based on different underlying-data structures. The | |
| main reason to choose a tree-based or trie-based container is if a | |
| byproduct of the tree-like structure is required: either | |
| order-preservation, or the ability to utilize node invariants. If | |
| memory-use is the major factor, an ordered-vector tree gives | |
| optimal results (albeit with high modificiation costs), and a | |
| list-based container gives reasonable results.</para> | |
| </section> | |
| <section xml:id="observations.associative.hash"> | |
| <info><title> | |
| Hash-Based Containers | |
| </title></info> | |
| <para>Hash-based containers are typically either collision | |
| chaining or probing. Collision-chaining | |
| containers are more flexible internally, and so offer better | |
| timing performance. Probing containers, if used for simple | |
| value-types, manage memory more efficiently (they perform far | |
| fewer allocation-related calls). In general, therefore, a | |
| collision-chaining table should be used. A probing container, | |
| conversely, might be used efficiently for operations such as | |
| eliminating duplicates in a sequence, or counting the number of | |
| occurrences within a sequence. Probing containers might be more | |
| useful also in multithreaded applications where each thread | |
| manipulates a hash-based container: in the standard, allocators have | |
| class-wise semantics (see [meyers96more] - Item 10); a | |
| probing container might incur less contention in this case.</para> | |
| </section> | |
| <section xml:id="observations.associative.hash_policies"> | |
| <info><title> | |
| Hash Policies | |
| </title></info> | |
| <para>In hash-based containers, the range-hashing scheme seems to | |
| affect performance more than other considerations. In most | |
| settings, a mask-based scheme works well (or can be made to | |
| work well). If the key-distribution can be estimated a-priori, | |
| a simple hash function can produce nearly uniform hash-value | |
| distribution. In many other cases (e.g., text hashing, | |
| floating-point hashing), the hash function is powerful enough | |
| to generate hash values with good uniformity properties | |
| [knuth98sorting]; | |
| a modulo-based scheme, taking into account all bits of the hash | |
| value, appears to overlap the hash function in its effort.</para> | |
| <para>The range-hashing scheme determines many of the other | |
| policies. A mask-based scheme works | |
| well with an exponential-size policy; for | |
| probing-based containers, it goes well with a linear-probe | |
| function.</para> | |
| <para>An orthogonal consideration is the trigger policy. This | |
| presents difficult tradeoffs. E.g., different load | |
| factors in a load-check trigger policy yield a | |
| space/amortized-cost tradeoff.</para> | |
| </section> | |
| <section xml:id="observations.associative.branch"> | |
| <info><title> | |
| Branch-Based Containers | |
| </title></info> | |
| <para>In general, there are several families of tree-based | |
| underlying data structures: balanced node-based trees | |
| (e.g., red-black or AVL trees), high-probability | |
| balanced node-based trees (e.g., random treaps or | |
| skip-lists), competitive node-based trees (e.g., splay | |
| trees), vector-based "trees", and tries. (Additionally, there | |
| are disk-residing or network-residing trees, such as B-Trees | |
| and their numerous variants. An interface for this would have | |
| to deal with the execution model and ACID guarantees; this is | |
| out of the scope of this library.) Following are some | |
| observations on their application to different settings.</para> | |
| <para>Of the balanced node-based trees, this library includes a | |
| red-black tree, as does standard (in | |
| practice). This type of tree is the "workhorse" of tree-based | |
| containers: it offers both reasonable modification and | |
| reasonable lookup time. Unfortunately, this data structure | |
| stores a huge amount of metadata. Each node must contain, | |
| besides a value, three pointers and a boolean. This type might | |
| be avoided if space is at a premium [austern00noset].</para> | |
| <para>High-probability balanced node-based trees suffer the | |
| drawbacks of deterministic balanced trees. Although they are | |
| fascinating data structures, preliminary tests with them showed | |
| their performance was worse than red-black trees. The library | |
| does not contain any such trees, therefore.</para> | |
| <para>Competitive node-based trees have two drawbacks. They are | |
| usually somewhat unbalanced, and they perform a large number of | |
| comparisons. Balanced trees perform one comparison per each | |
| node they encounter on a search path; a splay tree performs two | |
| comparisons. If the keys are complex objects, e.g., | |
| <classname>std::string</classname>, this can increase the running time. | |
| Conversely, such trees do well when there is much locality of | |
| reference. It is difficult to determine in which case to prefer | |
| such trees over balanced trees. This library includes a splay | |
| tree.</para> | |
| <para>Ordered-vector trees use very little space | |
| [austern00noset]. | |
| They do not have any other advantages (at least in this | |
| implementation).</para> | |
| <para>Large-fan-out PATRICIA tries have excellent lookup | |
| performance, but they do so through maintaining, for each node, | |
| a miniature "hash-table". Their space efficiency is low, and | |
| their modification performance is bad. These tries might be | |
| used for semi-static settings, where order preservation is | |
| important. Alternatively, red-black trees cross-referenced with | |
| hash tables can be used. [okasaki98mereable] | |
| discusses small-fan-out PATRICIA tries for integers, but the | |
| cited results seem to indicate that the amortized cost of | |
| maintaining such trees is higher than that of balanced trees. | |
| Moderate-fan-out trees might be useful for sequences where each | |
| element has a limited number of choices, e.g., DNA | |
| strings.</para> | |
| </section> | |
| <section xml:id="observations.associative.mapping_semantics"> | |
| <info><title> | |
| Mapping-Semantics | |
| </title></info> | |
| <para>Different mapping semantics were discussed in the introduction and design sections.Here | |
| the focus will be on the case where a keys can be composed into | |
| primary keys and secondary keys. (In the case where some keys | |
| are completely identical, it is trivial that one should use an | |
| associative container mapping values to size types.) In this | |
| case there are (at least) five possibilities:</para> | |
| <orderedlist> | |
| <listitem><para>Use an associative container that allows equivalent-key | |
| values (such as <classname>std::multimap</classname>)</para></listitem> | |
| <listitem><para>Use a unique-key value associative container that maps | |
| each primary key to some complex associative container of | |
| secondary keys, say a tree-based or hash-based container. | |
| </para></listitem> | |
| <listitem><para>Use a unique-key value associative container that maps | |
| each primary key to some simple associative container of | |
| secondary keys, say a list-based container.</para></listitem> | |
| <listitem><para>Use a unique-key value associative container that maps | |
| each primary key to some non-associative container | |
| (e.g., <classname>std::vector</classname>)</para></listitem> | |
| <listitem><para>Use a unique-key value associative container that takes | |
| into account both primary and secondary keys.</para></listitem> | |
| </orderedlist> | |
| <para>Stated simply: there is a simple answer for this. (Excluding | |
| option 1, which should be avoided in all cases).</para> | |
| <para>If the expected ratio of secondary keys to primary keys is | |
| small, then 3 and 4 seem reasonable. Both types of secondary | |
| containers are relatively lightweight (in terms of memory use | |
| and construction time), and so creating an entire container | |
| object for each primary key is not too expensive. Option 4 | |
| might be preferable to option 3 if changing the secondary key | |
| of some primary key is frequent - one cannot modify an | |
| associative container's key, and the only possibility, | |
| therefore, is erasing the secondary key and inserting another | |
| one instead; a non-associative container, conversely, can | |
| support in-place modification. The actual cost of erasing a | |
| secondary key and inserting another one depends also on the | |
| allocator used for secondary associative-containers (The tests | |
| above used the standard allocator, but in practice one might | |
| choose to use, e.g., [boost_pool]). Option 2 is | |
| definitely an overkill in this case. Option 1 loses out either | |
| immediately (when there is one secondary key per primary key) | |
| or almost immediately after that. Option 5 has the same | |
| drawbacks as option 2, but it has the additional drawback that | |
| finding all values whose primary key is equivalent to some key, | |
| might be linear in the total number of values stored (for | |
| example, if using a hash-based container).</para> | |
| <para>If the expected ratio of secondary keys to primary keys is | |
| large, then the answer is more complicated. It depends on the | |
| distribution of secondary keys to primary keys, the | |
| distribution of accesses according to primary keys, and the | |
| types of operations most frequent.</para> | |
| <para>To be more precise, assume there are m primary keys, | |
| primary key i is mapped to n<subscript>i</subscript> | |
| secondary keys, and each primary key is mapped, on average, to | |
| n secondary keys (i.e., | |
| E(n<subscript>i</subscript>) = n).</para> | |
| <para>Suppose one wants to find a specific pair of primary and | |
| secondary keys. Using 1 with a tree based container | |
| (<classname>std::multimap</classname>), the expected cost is | |
| E(Θ(log(m) + n<subscript>i</subscript>)) = Θ(log(m) + | |
| n); using 1 with a hash-based container | |
| (<classname>std::tr1::unordered_multimap</classname>), the expected cost is | |
| Θ(n). Using 2 with a primary hash-based container | |
| and secondary hash-based containers, the expected cost is | |
| O(1); using 2 with a primary tree-based container and | |
| secondary tree-based containers, the expected cost is (using | |
| the Jensen inequality [motwani95random]) | |
| E(O(log(m) + log(n<subscript>i</subscript>)) = O(log(m)) + | |
| E(O(log(n<subscript>i</subscript>)) = O(log(m)) + O(log(n)), | |
| assuming that primary keys are accessed equiprobably. 3 and 4 | |
| are similar to 1, but with lower constants. Using 5 with a | |
| hash-based container, the expected cost is O(1); using 5 | |
| with a tree based container, the cost is | |
| E(Θ(log(mn))) = Θ(log(m) + | |
| log(n)).</para> | |
| <para>Suppose one needs the values whose primary key matches some | |
| given key. Using 1 with a hash-based container, the expected | |
| cost is Θ(n), but the values will not be ordered | |
| by secondary keys (which may or may not be required); using 1 | |
| with a tree-based container, the expected cost is | |
| Θ(log(m) + n), but with high constants; again the | |
| values will not be ordered by secondary keys. 2, 3, and 4 are | |
| similar to 1, but typically with lower constants (and, | |
| additionally, if one uses a tree-based container for secondary | |
| keys, they will be ordered). Using 5 with a hash-based | |
| container, the cost is Θ(mn).</para> | |
| <para>Suppose one wants to assign to a primary key all secondary | |
| keys assigned to a different primary key. Using 1 with a | |
| hash-based container, the expected cost is Θ(n), | |
| but with very high constants; using 1 with a tree-based | |
| container, the cost is Θ(nlog(mn)). Using 2, 3, | |
| and 4, the expected cost is Θ(n), but typically | |
| with far lower costs than 1. 5 is similar to 1.</para> | |
| </section> | |
| </section> | |
| <section xml:id="observations.priority_queue"> | |
| <info><title>Priority_Queue</title></info> | |
| <section xml:id="observations.priority_queue.complexity"> | |
| <info><title>Complexity</title></info> | |
| <para>The following table shows the complexities of the different | |
| underlying data structures in terms of orders of growth. It is | |
| interesting to note that this table implies something about the | |
| constants of the operations as well (see Amortized <function>push</function> | |
| and <function>pop</function> operations).</para> | |
| <informaltable frame="all"> | |
| <tgroup cols="6" align="left" colsep="1" rowsep="1"> | |
| <colspec colname="c1"/> | |
| <colspec colname="c2"/> | |
| <colspec colname="c3"/> | |
| <colspec colname="c4"/> | |
| <colspec colname="c5"/> | |
| <colspec colname="c6"/> | |
| <thead> | |
| <row> | |
| <entry></entry> | |
| <entry><emphasis><function>push</function></emphasis></entry> | |
| <entry><emphasis><function>pop</function></emphasis></entry> | |
| <entry><emphasis><function>modify</function></emphasis></entry> | |
| <entry><emphasis><function>erase</function></emphasis></entry> | |
| <entry><emphasis><function>join</function></emphasis></entry> | |
| </row> | |
| </thead> | |
| <tbody> | |
| <row> | |
| <entry> | |
| <classname>std::priority_queue</classname> | |
| </entry> | |
| <entry> | |
| Θ(n) worst | |
| Θ(log(n)) amortized | |
| </entry> | |
| <entry> | |
| Θ(log(n)) Worst | |
| </entry> | |
| <entry> | |
| Θ(n log(n)) Worst | |
| <subscript>[std note 1]</subscript> | |
| </entry> | |
| <entry> | |
| Θ(n log(n)) | |
| <subscript>[std note 2]</subscript> | |
| </entry> | |
| <entry> | |
| Θ(n log(n)) | |
| <subscript>[std note 1]</subscript> | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| <<classname>Tag</classname> = | |
| <classname>pairing_heap_tag</classname>> | |
| </entry> | |
| <entry> | |
| O(1) | |
| </entry> | |
| <entry> | |
| Θ(n) worst | |
| Θ(log(n)) amortized | |
| </entry> | |
| <entry> | |
| Θ(n) worst | |
| Θ(log(n)) amortized | |
| </entry> | |
| <entry> | |
| Θ(n) worst | |
| Θ(log(n)) amortized | |
| </entry> | |
| <entry> | |
| O(1) | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| <<classname>Tag</classname> = | |
| <classname>binary_heap_tag</classname>> | |
| </entry> | |
| <entry> | |
| Θ(n) worst | |
| Θ(log(n)) amortized | |
| </entry> | |
| <entry> | |
| Θ(n) worst | |
| Θ(log(n)) amortized | |
| </entry> | |
| <entry> | |
| Θ(n) | |
| </entry> | |
| <entry> | |
| Θ(n) | |
| </entry> | |
| <entry> | |
| Θ(n) | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| <<classname>Tag</classname> = | |
| <classname>binomial_heap_tag</classname>> | |
| </entry> | |
| <entry> | |
| Θ(log(n)) worst | |
| O(1) amortized | |
| </entry> | |
| <entry> | |
| Θ(log(n)) | |
| </entry> | |
| <entry> | |
| Θ(log(n)) | |
| </entry> | |
| <entry> | |
| Θ(log(n)) | |
| </entry> | |
| <entry> | |
| Θ(log(n)) | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname> | |
| <<classname>Tag</classname> = | |
| <classname>rc_binomial_heap_tag</classname>> | |
| </entry> | |
| <entry> | |
| O(1) | |
| </entry> | |
| <entry> | |
| Θ(log(n)) | |
| </entry> | |
| <entry> | |
| Θ(log(n)) | |
| </entry> | |
| <entry> | |
| Θ(log(n)) | |
| </entry> | |
| <entry> | |
| Θ(log(n)) | |
| </entry> | |
| </row> | |
| <row> | |
| <entry> | |
| <classname>priority_queue</classname><<classname>Tag</classname> = | |
| <classname>thin_heap_tag</classname>> | |
| </entry> | |
| <entry> | |
| O(1) | |
| </entry> | |
| <entry> | |
| Θ(n) worst | |
| Θ(log(n)) amortized | |
| </entry> | |
| <entry> | |
| Θ(log(n)) worst | |
| O(1) amortized, | |
| or Θ(log(n)) amortized | |
| <subscript>[thin_heap_note]</subscript> | |
| </entry> | |
| <entry> | |
| Θ(n) worst | |
| Θ(log(n)) amortized | |
| </entry> | |
| <entry> | |
| Θ(n) | |
| </entry> | |
| </row> | |
| </tbody> | |
| </tgroup> | |
| </informaltable> | |
| <para>[std note 1] This | |
| is not a property of the algorithm, but rather due to the fact | |
| that the standard's priority queue implementation does not support | |
| iterators (and consequently the ability to access a specific | |
| value inside it). If the priority queue is adapting an | |
| <classname>std::vector</classname>, then it is still possible to reduce this | |
| to Θ(n) by adapting over the standard's adapter and | |
| using the fact that <function>top</function> returns a reference to the | |
| first value; if, however, it is adapting an | |
| <classname>std::deque</classname>, then this is impossible.</para> | |
| <para>[std note 2] As | |
| with [std note 1], this is not a | |
| property of the algorithm, but rather the standard's implementation. | |
| Again, if the priority queue is adapting an | |
| <classname>std::vector</classname> then it is possible to reduce this to | |
| Θ(n), but with a very high constant (one must call | |
| <function>std::make_heap</function> which is an expensive linear | |
| operation); if the priority queue is adapting an | |
| <classname>std::deque</classname>, then this is impossible.</para> | |
| <para>[thin_heap_note] A thin heap has | |
| Θ(log(n)) worst case <function>modify</function> time | |
| always, but the amortized time depends on the nature of the | |
| operation: I) if the operation increases the key (in the sense | |
| of the priority queue's comparison functor), then the amortized | |
| time is O(1), but if II) it decreases it, then the | |
| amortized time is the same as the worst case time. Note that | |
| for most algorithms, I) is important and II) is not.</para> | |
| </section> | |
| <section xml:id="observations.priority_queue.amortized_ops"> | |
| <info><title> | |
| Amortized <function>push</function> | |
| and <function>pop</function> operations | |
| </title></info> | |
| <para>In many cases, a priority queue is needed primarily for | |
| sequences of <function>push</function> and <function>pop</function> operations. All of | |
| the underlying data structures have the same amortized | |
| logarithmic complexity, but they differ in terms of | |
| constants.</para> | |
| <para>The table above shows that the different data structures are | |
| "constrained" in some respects. In general, if a data structure | |
| has lower worst-case complexity than another, then it will | |
| perform slower in the amortized sense. Thus, for example a | |
| redundant-counter binomial heap (<classname>priority_queue</classname> with | |
| <classname>Tag</classname> = <classname>rc_binomial_heap_tag</classname>) | |
| has lower worst-case <function>push</function> performance than a binomial | |
| heap (<classname>priority_queue</classname> | |
| with <classname>Tag</classname> = <classname>binomial_heap_tag</classname>), | |
| and so its amortized <function>push</function> performance is slower in | |
| terms of constants.</para> | |
| <para>As the table shows, the "least constrained" underlying | |
| data structures are binary heaps and pairing heaps. | |
| Consequently, it is not surprising that they perform best in | |
| terms of amortized constants.</para> | |
| <orderedlist> | |
| <listitem><para>Pairing heaps seem to perform best for non-primitive | |
| types (e.g., <classname>std::string</classname>s), as shown by | |
| Priority | |
| Queue Text <function>push</function> Timing Test and Priority | |
| Queue Text <function>push</function> and <function>pop</function> Timing | |
| Test</para></listitem> | |
| <listitem><para>binary heaps seem to perform best for primitive types | |
| (e.g., <type>int</type>s), as shown by Priority | |
| Queue Random Integer <function>push</function> Timing Test and | |
| Priority | |
| Queue Random Integer <function>push</function> and <function>pop</function> Timing | |
| Test.</para></listitem> | |
| </orderedlist> | |
| </section> | |
| <section xml:id="observations.priority_queue.graphs"> | |
| <info><title> | |
| Graph Algorithms | |
| </title></info> | |
| <para>In some graph algorithms, a decrease-key operation is | |
| required [clrs2001]; | |
| this operation is identical to <function>modify</function> if a value is | |
| increased (in the sense of the priority queue's comparison | |
| functor). The table above and Priority Queue | |
| Text <function>modify</function> Up Timing Test show that a thin heap | |
| (<classname>priority_queue</classname> with | |
| <classname>Tag</classname> = <classname>thin_heap_tag</classname>) | |
| outperforms a pairing heap (<classname>priority_queue</classname> with | |
| <classname>Tag</classname> = <classname>Tag</classname> = <classname>pairing_heap_tag</classname>), | |
| but the rest of the tests show otherwise.</para> | |
| <para>This makes it difficult to decide which implementation to use in | |
| this case. Dijkstra's shortest-path algorithm, for example, requires | |
| Θ(n) <function>push</function> and <function>pop</function> operations | |
| (in the number of vertices), but O(n<superscript>2</superscript>) | |
| <function>modify</function> operations, which can be in practice Θ(n) | |
| as well. It is difficult to find an a-priori characterization of | |
| graphs in which the actual number of <function>modify</function> | |
| operations will dwarf the number of <function>push</function> and | |
| <function>pop</function> operations.</para> | |
| </section> | |
| </section> <!-- priority_queue --> | |
| </section> | |
| </section> <!-- performance --> | |
| </section> |