|
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="pt-BR">
|
|
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>Listas vinculadas e tipos contêineres</desc>
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
<mal:credit xmlns:mal="http://projectmallard.org/1.0/" type="translator copyright">
|
|
Packit |
1470ea |
<mal:name>Rafael Fontenelle</mal:name>
|
|
Packit |
1470ea |
<mal:email>rafaelff@gnome.org</mal:email>
|
|
Packit |
1470ea |
<mal:years>2017</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>Uso do GList</title>
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
GLib fornece vários tipos contêineres para conjuntos de dados: <link href="https://developer.gnome.org/glib/stable/glib-Doubly-Linked-Lists.html">GList </link>, <link href="https://developer.gnome.org/glib/stable/glib-Singly-Linked-Lists.html">GSList </link>, <link href="https://developer.gnome.org/glib/stable/glib-Pointer-Arrays.html">GPtrArray </link> e <link href="https://developer.gnome.org/glib/stable/glib-Arrays.html">GArray </link>.
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
Foi uma prática comum no passado usar GList e, todas situações nas quais uma sequência ou conjunto de dados precisa ser armazenada(o). Isso não é recomendável — na maioria das situações, um GPtrArray deve ser usado. Ele faz menor uso de memória (um terço a metade de uma lista equivalente), melhora localidade de cache e a mesma ou menor complexidade algorítmica para todas as operações comuns. A única situação típica na qual um GList pode ser mais apropriado é ao lidar com dados ordenados, que requer inserções custosas em índices arbitrários no vetor.
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
Se listas vinculadas forem usadas, tenha o cuidado de manter baixa a complexidade das operações nelas, usando análise padrão de complexidade CS. Qualquer operação que usa <link href="https://developer.gnome.org/glib/2.30/glib-Doubly-Linked-Lists.html#g-list-nth">g_list_nth() </link> ou <link href="https://developer.gnome.org/glib/2.30/glib-Doubly-Linked-Lists.html#g-list-nth-data">g_list_nth_data() </link> está quase certamente errada. Por exemplo, interação por um GList deve ser implementada usando os ponteiros vinculantes, em vez de um índice incremental:
|
|
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 |
/* Faz alguma coisa com @element_data. */
|
|
Packit |
1470ea |
}
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
Usar um índice incremental pode resultar em um decréscimo quadrático no desempenho (O(N^2) em vez de O(N)):
|
|
Packit |
1470ea |
GList *some_list;
|
|
Packit |
1470ea |
guint i;
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
/* Esse código é ineficiente e não deve ser usado em produção. */
|
|
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 |
/* Faz alguma coisa com @element_data. */
|
|
Packit |
1470ea |
}
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
A penalidade no desempenho vem de g_list_length() e de g_list_nth_data() , os quais percorrem a lista (O(N)) para realizar suas operações.
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
Implementar o código acima com um GPtrArray tem a mesma complexidade que a primeira (correta) implementação de GList, mas com melhor localidade de cache e menor consumo de memória, de forma a executar melhor para grandes números de elementos:
|
|
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 |
/* Faz alguma coisa com @element_data. */
|
|
Packit |
1470ea |
}
|
|
Packit |
1470ea |
</section>
|
|
Packit |
1470ea |
</page>
|