Pular para o conteúdo

Custo das estruturas

O que cada operação de cluster, vault e string realmente custa.

Escolher a estrutura certa costuma render mais que otimizar o algoritmo. Esta é a tabela que decide.

Cluster#

OperaçãoCustoPor quê
xs[i]O(1)acesso direto pelo índice
xs.append(x)O(1)*amortizado — ver casos
xs.pop()O(1)remove do fim
xs.pop(0)O(n)desloca todos os outros
xs.insert(0, x)O(n)idem
x in xsO(n)percorre até achar
xs.index_of(x)O(n)idem
xs.remove(x)O(n)procura e desloca
len(xs)O(1)o tamanho é guardado
xs[a:b]O(b−a)copia a fatia
xs.sort()O(n log n)ordenação por comparação
xs.reverse()O(n)troca aos pares
sum(xs), max(xs)O(n)percorre uma vez
[...a, ...b]O(n+m)copia os dois

Vault#

OperaçãoCustoPor quê
v[chave]O(1)tabela de espalhamento
v[chave] := xO(1)idem
v.has(chave)O(1)idem
chave in vO(1)idem
v.get(chave, padrao)O(1)idem
delete v[chave]O(1)idem
v.keys()O(n)monta o cluster
v.values()O(n)idem
v.items()O(n)idem
len(v)O(1)guardado

O vault é a estrutura mais subutilizada da linguagem. Quase todo O(n²) acidental some ao trocar uma busca linear por uma consulta de vault.

String#

OperaçãoCustoPor quê
s[i]O(1)acesso direto
len(s)O(1)guardado
a + bO(n+m)cria uma string nova
s.contains(t)O(n·m)compara em cada posição
s.split(sep)O(n)uma passada
sep.join(xs)O(n)aloca uma vez
s.replace(a, b)O(n)uma passada
s.upper()O(n)cria uma nova
s[a:b]O(b−a)copia

Record e blueprint#

OperaçãoCusto
p.campoO(1)
p with {...}O(k) — k campos
spawn X(...)O(k) — k campos
p1 is p2 (record)O(k) — compara campo a campo
chamar um métodoO(1) + o corpo
root.metodo()O(d) — d = profundidade da herança

Escolhendo#

Você precisa de…UsePor quê
ordem e índiceClusteracesso O(1) por posição
procurar por chaveVaultO(1) contra O(n)
itens únicosVault com valor yesa chave já garante unicidade
contar ocorrênciasxs.tally()uma passada, O(n)
agruparxs.group_by(f)uma passada, O(n)
valor imutávelrecordigualdade estrutural, serve de chave
entidade com estadoblueprintidentidade própria