Blame programming-guidelines/de/glist.page

Packit 1470ea
Packit 1470ea
<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="de">
Packit 1470ea
Packit 1470ea
  <info>
Packit 1470ea
    <link type="guide" xref="index#specific-how-tos"/>
Packit 1470ea
Packit 1470ea
    <credit type="author copyright">
Packit 1470ea
      <name>Philip Withnall</name>
Packit 1470ea
      <email its:translate="no">philip.withnall@collabora.co.uk</email>
Packit 1470ea
      <years>2015</years>
Packit 1470ea
    </credit>
Packit 1470ea
Packit 1470ea
    <include xmlns="http://www.w3.org/2001/XInclude" href="cc-by-sa-3-0.xml"/>
Packit 1470ea
Packit 1470ea
    <desc>Linked lists and container types</desc>
Packit 1470ea
  
Packit 1470ea
    <mal:credit xmlns:mal="http://projectmallard.org/1.0/" type="translator copyright">
Packit 1470ea
      <mal:name>Mario Blättermann</mal:name>
Packit 1470ea
      <mal:email>mario.blaettermann@gmail.com</mal:email>
Packit 1470ea
      <mal:years>2016</mal:years>
Packit 1470ea
    </mal:credit>
Packit 1470ea
  
Packit 1470ea
    <mal:credit xmlns:mal="http://projectmallard.org/1.0/" type="translator copyright">
Packit 1470ea
      <mal:name>Christian Kirbach</mal:name>
Packit 1470ea
      <mal:email>christian.kirbach@gmail.com</mal:email>
Packit 1470ea
      <mal:years>2016</mal:years>
Packit 1470ea
    </mal:credit>
Packit 1470ea
  </info>
Packit 1470ea
Packit 1470ea
  <title>GList</title>
Packit 1470ea
Packit 1470ea
  <section id="glist-usage">
Packit 1470ea
    <title>Verwendung von GList</title>
Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      GLib provides several container types for sets of data:
Packit 1470ea
      <link href="https://developer.gnome.org/glib/stable/glib-Doubly-Linked-Lists.html">GList</link>,
Packit 1470ea
      <link href="https://developer.gnome.org/glib/stable/glib-Singly-Linked-Lists.html">GSList</link>,
Packit 1470ea
      <link href="https://developer.gnome.org/glib/stable/glib-Pointer-Arrays.html">GPtrArray</link> and
Packit 1470ea
      <link href="https://developer.gnome.org/glib/stable/glib-Arrays.html">GArray</link>.
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      It has been common practice in the past to use GList in all situations
Packit 1470ea
      where a sequence or set of data needs to be stored. This is inadvisable —
Packit 1470ea
      in most situations, a GPtrArray should be used instead. It has lower
Packit 1470ea
      memory overhead (a third to a half of an equivalent list), better cache
Packit 1470ea
      locality, and the same or lower algorithmic complexity for all common
Packit 1470ea
      operations. The only typical situation where a GList may be more
Packit 1470ea
      appropriate is when dealing with ordered data, which requires expensive
Packit 1470ea
      insertions at arbitrary indexes in the array.
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      If linked lists are used, be careful to keep the complexity of operations
Packit 1470ea
      on them low, using standard CS complexity analysis. Any operation which
Packit 1470ea
      uses
Packit 1470ea
      <link href="https://developer.gnome.org/glib/2.30/glib-Doubly-Linked-Lists.html#g-list-nth">g_list_nth()</link> or
Packit 1470ea
      <link href="https://developer.gnome.org/glib/2.30/glib-Doubly-Linked-Lists.html#g-list-nth-data">g_list_nth_data()</link>
Packit 1470ea
      is almost certainly wrong. For example, iteration over a GList should be
Packit 1470ea
      implemented using the linking pointers, rather than a incrementing index:
Packit 1470ea
    

Packit 1470ea
    GList *some_list, *l;
Packit 1470ea
Packit 1470ea
for (l = some_list; l != NULL; l = l->next)
Packit 1470ea
  {
Packit 1470ea
    gpointer element_data = l->data;
Packit 1470ea
Packit 1470ea
    /* Do something with @element_data. */
Packit 1470ea
  }
Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      Using an incrementing index instead results in a quadratic decrease in
Packit 1470ea
      performance (O(N^2) rather than O(N)):
Packit 1470ea
    

Packit 1470ea
    GList *some_list;
Packit 1470ea
guint i;
Packit 1470ea
Packit 1470ea
/* This code is inefficient and should not be used in production. */
Packit 1470ea
for (i = 0; i < g_list_length (some_list); i++)
Packit 1470ea
  {
Packit 1470ea
    gpointer element_data = g_list_nth_data (some_list, i);
Packit 1470ea
Packit 1470ea
    /* Do something with @element_data. */
Packit 1470ea
  }
Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      The performance penalty comes from g_list_length() and
Packit 1470ea
      g_list_nth_data() which both traverse the list
Packit 1470ea
      (O(N)) to perform their operations.
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      Implementing the above with a GPtrArray has the same complexity as the
Packit 1470ea
      first (correct) GList implementation, but better cache locality and lower
Packit 1470ea
      memory consumption, so will perform better for large numbers of elements:
Packit 1470ea
    

Packit 1470ea
    GPtrArray *some_array;
Packit 1470ea
guint i;
Packit 1470ea
Packit 1470ea
for (i = 0; i < some_array->len; i++)
Packit 1470ea
  {
Packit 1470ea
    gpointer element_data = some_array->pdata[i];
Packit 1470ea
Packit 1470ea
    /* Do something with @element_data. */
Packit 1470ea
  }
Packit 1470ea
  </section>
Packit 1470ea
</page>