Blob Blame History Raw
<?xml version="1.0" encoding="utf-8"?>
<page xmlns="http://projectmallard.org/1.0/" xmlns:its="http://www.w3.org/2005/11/its" xmlns:xi="http://www.w3.org/2003/XInclude" type="topic" id="glist" xml:lang="cs">

  <info>
    <link type="guide" xref="index#specific-how-tos"/>

    <credit type="author copyright">
      <name>Philip Withnall</name>
      <email its:translate="no">philip.withnall@collabora.co.uk</email>
      <years>2015</years>
    </credit>

    <include xmlns="http://www.w3.org/2001/XInclude" href="cc-by-sa-3-0.xml"/>

    <desc>Propojené seznamy a kontejnerové typy</desc>
  </info>

  <title>GList</title>

  <section id="glist-usage">
    <title>Použití GList</title>

    <p>GLib poskytuje někoklik kontejnerových typů pro množiny dat: <link href="https://developer.gnome.org/glib/stable/glib-Doubly-Linked-Lists.html"><code>GList</code></link>, <link href="https://developer.gnome.org/glib/stable/glib-Singly-Linked-Lists.html"><code>GSList</code></link>, <link href="https://developer.gnome.org/glib/stable/glib-Pointer-Arrays.html"><code>GPtrArray</code></link> a <link href="https://developer.gnome.org/glib/stable/glib-Arrays.html"><code>GArray</code></link>.</p>

    <p>Dříve bylo běžnou praxí používat GList ve všech situacích, kdy bylo zapotřebí uchovat řadu nebo množinu dat. To ale není rozumné — ve většině situací by místo něj měl být použit GPtrArray. Má menší paměťové nároky (třetinové až poloviční oproti obdobnému seznamu), lepší dostupnost z mezipaměti a stejnou nebo menší algoritmickou složitost pro všechny běžné operace. Jedinou typickou situací, kdy může být GList vhodnější, je při práci se uspořádanými daty ve kterých je požadováno masivní vkládání na libovolné místo v poli.</p>

    <p>Když jsou použité zřetězené seznamy, dávejte pozor, aby složitost operací zůstala na rozumné úrovni podle standardní analýzy složitosti v matematické informatice. Kterákoliv operace, která používá <link href="https://developer.gnome.org/glib/2.30/glib-Doubly-Linked-Lists.html#g-list-nth"><code>g_list_nth()</code></link> nebo <link href="https://developer.gnome.org/glib/2.30/glib-Doubly-Linked-Lists.html#g-list-nth-data"><code>g_list_nth_data()</code></link>, je povětšinou úplně špatně. Například iterace přes GList by měla být implementována pomocí zřetězujících ukazatelů a ne postupným zvyšováním indexu.</p>
    <code mime="text/x-csrc" style="valid">GList *some_list, *l;

for (l = some_list; l != NULL; l = l-&gt;next)
  {
    gpointer element_data = l-&gt;data;

    /* Provedení něčeho s @element_data. */
  }</code>

    <p>Když se místo toho použije postupné zvyšování indexu, je výsledkem kvadratické snížení výkonu (<em>O(N^2)</em> namísto <em>O(N)</em>):</p>
    <code mime="text/x-csrc" style="invalid">GList *some_list;
guint i;

/* Tento algoritmus je neefektivní a neměl by být použit v produkčním kódu. */
for (i = 0; i &lt; g_list_length (some_list); i++)
  {
    gpointer element_data = g_list_nth_data (some_list, i);

    /* Provedení něčeho s @element_data. */
  }</code>

    <p>Snížení výkonu nastává ve funkcích <code>g_list_length()</code> a <code>g_list_nth_data()</code>, které obě kvůli provedení své operace pole procházejí (<em>O(N)</em>).</p>

    <p>Implementace kódu uvedeného výše pomocí GPtrArray má stejnou složitost pro první (správnou) implementaci GList, ale lepší dostupnost z mezipaměti a nižší spotřebu paměti, takže bude mít lepší výkon pro velké množství prvků:</p>
    <code mime="text/x-csrc" style="valid">GPtrArray *some_array;
guint i;

for (i = 0; i &lt; some_array-&gt;len; i++)
  {
    gpointer element_data = some_array-&gt;pdata[i];

    /* Provedení něčeho s @element_data. */
  }</code>
  </section>
</page>