File: glist.page

package info (click to toggle)
gnome-devel-docs 40.3-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 79,188 kB
  • sloc: javascript: 2,514; xml: 2,407; ansic: 2,229; python: 1,854; makefile: 805; sh: 499; cpp: 131
file content (104 lines) | stat: -rw-r--r-- 4,352 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
<?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="es">

  <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>Listas enlazadas y tipos de contenedores</desc>
  
    <mal:credit xmlns:mal="http://projectmallard.org/1.0/" type="translator copyright">
      <mal:name>Daniel Mustieles</mal:name>
      <mal:email>daniel.mustieles@gmail.com</mal:email>
      <mal:years>2016-2020</mal:years>
    </mal:credit>
  
    <mal:credit xmlns:mal="http://projectmallard.org/1.0/" type="translator copyright">
      <mal:name>Javier Mazorra</mal:name>
      <mal:email>mazi.debian@gmail.com</mal:email>
      <mal:years>2016, 2020</mal:years>
    </mal:credit>
  </info>

  <title>GList</title>

  <section id="glist-usage">
    <title>Uso de GList</title>

    <p>
      GLib provides several container types for sets of data:
      <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> and
      <link href="https://developer.gnome.org/glib/stable/glib-Arrays.html"><code>GArray</code></link>.
    </p>

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

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

    /* Do something with @element_data. */
  }</code>

    <p>
      Using an incrementing index instead results in a quadratic decrease in
      performance (<em>O(N^2)</em> rather than <em>O(N)</em>):
    </p>
    <code mime="text/x-csrc" style="invalid">GList *some_list;
guint i;

/* This code is inefficient and should not be used in production. */
for (i = 0; i &lt; g_list_length (some_list); i++)
  {
    gpointer element_data = g_list_nth_data (some_list, i);

    /* Do something with @element_data. */
  }</code>

    <p>
      The performance penalty comes from <code>g_list_length()</code> and
      <code>g_list_nth_data()</code> which both traverse the list
      (<em>O(N)</em>) to perform their operations.
    </p>

    <p>La implementación de lo anterior con un GPtrArray tiene la misma complejidad que la primera implementación GList (correcta), pero mejor localidad de caché y menor consumo de memoria, por lo que funcionará mejor para un gran número de elementos:</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];

    /* Do something with @element_data. */
  }</code>
  </section>
</page>