Skip to content

Adiciona método Contains e marca InArray como deprecado - #10

Merged
fm4teus merged 2 commits into
StudioSol:masterfrom
fm4teus:contains
Oct 2, 2025
Merged

Adiciona método Contains e marca InArray como deprecado#10
fm4teus merged 2 commits into
StudioSol:masterfrom
fm4teus:contains

Conversation

@fm4teus

@fm4teusfm4teus commented Oct 1, 2025

Copy link
Copy Markdown
Member

Problema

Método InArray verifica existencia de um item no set, no entanto ele itera por todo o set, por isso sua complexidade é O(n);

Aproveitando o método Get que usa tabela hash foi implementado o método Contains, que resolve o problema em O(1) (desconsiderando colisões de hash aqui)

Benchmark

NCasoContains (ns/op)InArray (ns/op)Contains (B/op)InArray (B/op)
20000Found159.01,300,42924491,804
20000NotFound242.61,782,24040491,781
40000Found155.82,409,34124975,117
40000NotFound225.83,536,61940975,124
60000Found186.44,663,344241,450,258
60000NotFound239.06,492,405401,450,237
80000Found160.55,832,141241,933,580
80000NotFound264.68,301,901401,933,565
100000Found163.27,531,702242,408,700
100000NotFound236.510,035,038402,408,730
imageimage
Running tool: /usr/bin/go test -benchmem -run=^$ -bench ^BenchmarkLinkedHashSet_Contains_vs_InArray$ github.com/StudioSol/set
goos: linux
goarch: amd64
pkg: github.com/StudioSol/set
cpu: 11th Gen Intel(R) Core(TM) i7-11390H @ 3.40GHz
BenchmarkLinkedHashSet_Contains_vs_InArray/N=20000/Found/Contains-8 7893087 159.0 ns/op 24 B/op 2 allocs/op
BenchmarkLinkedHashSet_Contains_vs_InArray/N=20000/Found/InArray-8 960 1300429 ns/op 491804 B/op 6 allocs/op
BenchmarkLinkedHashSet_Contains_vs_InArray/N=20000/NotFound/Contains-8 5032278 242.6 ns/op 40 B/op 2 allocs/op
BenchmarkLinkedHashSet_Contains_vs_InArray/N=20000/NotFound/InArray-8 644 1782240 ns/op 491781 B/op 6 allocs/op
BenchmarkLinkedHashSet_Contains_vs_InArray/N=40000/Found/Contains-8 7268748 155.8 ns/op 24 B/op 2 allocs/op
BenchmarkLinkedHashSet_Contains_vs_InArray/N=40000/Found/InArray-8 505 2409341 ns/op 975117 B/op 6 allocs/op
BenchmarkLinkedHashSet_Contains_vs_InArray/N=40000/NotFound/Contains-8 5115067 225.8 ns/op 40 B/op 2 allocs/op
BenchmarkLinkedHashSet_Contains_vs_InArray/N=40000/NotFound/InArray-8 367 3536619 ns/op 975124 B/op 6 allocs/op
BenchmarkLinkedHashSet_Contains_vs_InArray/N=60000/Found/Contains-8 6690541 186.4 ns/op 24 B/op 2 allocs/op
BenchmarkLinkedHashSet_Contains_vs_InArray/N=60000/Found/InArray-8 264 4663344 ns/op 1450258 B/op 6 allocs/op
BenchmarkLinkedHashSet_Contains_vs_InArray/N=60000/NotFound/Contains-8 4386883 239.0 ns/op 40 B/op 2 allocs/op
BenchmarkLinkedHashSet_Contains_vs_InArray/N=60000/NotFound/InArray-8 193 6492405 ns/op 1450237 B/op 6 allocs/op
BenchmarkLinkedHashSet_Contains_vs_InArray/N=80000/Found/Contains-8 6602422 160.5 ns/op 24 B/op 2 allocs/op
BenchmarkLinkedHashSet_Contains_vs_InArray/N=80000/Found/InArray-8 218 5832141 ns/op 1933580 B/op 6 allocs/op
BenchmarkLinkedHashSet_Contains_vs_InArray/N=80000/NotFound/Contains-8 4031731 264.6 ns/op 40 B/op 2 allocs/op
BenchmarkLinkedHashSet_Contains_vs_InArray/N=80000/NotFound/InArray-8 145 8301901 ns/op 1933565 B/op 6 allocs/op
BenchmarkLinkedHashSet_Contains_vs_InArray/N=100000/Found/Contains-8 6620458 163.2 ns/op 24 B/op 2 allocs/op
BenchmarkLinkedHashSet_Contains_vs_InArray/N=100000/Found/InArray-8 165 7531702 ns/op 2408700 B/op 6 allocs/op
BenchmarkLinkedHashSet_Contains_vs_InArray/N=100000/NotFound/Contains-8 4256808 236.5 ns/op 40 B/op 2 allocs/op
BenchmarkLinkedHashSet_Contains_vs_InArray/N=100000/NotFound/InArray-8 100 10035038 ns/op 2408730 B/op 6 allocs/op
PASS
ok github.com/StudioSol/set	30.082s

@fm4teusfm4teus self-assigned this Oct 1, 2025
@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello @fm4teus, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

Este pull request otimiza significativamente a verificação de existência de itens dentro de um LinkedHashSet. A mudança principal é a introdução de um método Contains com complexidade de tempo média O(1), que substitui o método InArray de complexidade O(n). Esta melhoria é crucial para o desempenho em conjuntos grandes e é complementada pela atualização da assinatura do método Get para uma abordagem mais idiomática em Go, garantindo clareza e eficiência.

Highlights

  • Novo método Contains: Foi adicionado um novo método Contains ao LinkedHashSet para verificar a existência de um item de forma eficiente.
  • Depreciação de InArray: O método InArray foi marcado como depreciado devido à sua complexidade de tempo O(n), incentivando o uso do novo método Contains.
  • Melhoria de Performance: O método Contains aproveita a tabela hash subjacente para alcançar uma complexidade de tempo média de O(1), resultando em ganhos de performance significativos em comparação com InArray.
  • Alteração na assinatura do método Get: A assinatura do método Get em linkedHashMap foi atualizada para retornar (value interface{}, found bool), seguindo a prática idiomática do Go para indicar a presença de um valor.
  • Benchmarks e Testes: Foram adicionados novos benchmarks e testes unitários para validar o método Contains e demonstrar seus benefícios de desempenho.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

FeatureCommandDescription
Code Review/gemini reviewPerforms a code review for the current pull request in its current state.
Pull Request Summary/gemini summaryProvides a summary of the current pull request in its current state.
Comment@gemini-code-assistResponds in comments when explicitly tagged, both in pull request comments and review comments.
Help/gemini helpDisplays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assistgemini-code-assistBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

Olá! Obrigado pela contribuição. A adição do método Contains e a depreciação do InArray é uma excelente melhoria de performance, como demonstrado pelos benchmarks. A mudança na assinatura do método Get em linkedhashmap para retornar um booleano indicando a existência da chave também é uma ótima prática em Go.

Durante a revisão, identifiquei um problema crítico na implementação do linkedHashMap que afeta a corretude e a performance do método Get, e consequentemente do novo método Contains. Também encontrei algumas chamadas de depuração que foram deixadas no código de teste.

Por favor, veja meus comentários nos arquivos para mais detalhes.

Comment threadlinkedhashmap.go
Comment on lines 70 to +78
tmp := l.table[hash]
for tmp != nil {
if tmp.key == key {
return tmp.value
return tmp.value, true
}
tmp = tmp.after
}

return nil
return nil, false

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

Olá! A mudança na assinatura do método Get é uma boa melhoria. No entanto, identifiquei um problema crítico de corretude e performance na implementação do linkedHashMap que invalida a premissa de complexidade O(1) para o Get e, consequentemente, para o novo método Contains.

  1. Tratamento de Colisão em Put: O método Put (não presente neste diff, mas parte do contexto) não trata colisões de hash. Ele simplesmente retorna se um hash já existe (if _, ok := l.table[hash]; ok { return }). Isso significa que se duas chaves diferentes produzirem o mesmo hash, a segunda chave e seu valor serão descartados, o que é um bug grave.

  2. Lógica de Busca em Get: O laço for (linhas 71-76) itera sobre a lista de ordem de inserção (tmp.after), não sobre uma cadeia de colisões. Isso é incorreto para resolver colisões e degrada a performance de O(1) para O(n) no pior caso, pois pode percorrer grande parte da lista.

Para que o Get (e o Contains) tenha a performance esperada, o linkedHashMap precisa ser corrigido para tratar colisões de hash adequadamente, por exemplo, usando encadeamento separado (separate chaining) para cada bucket no mapa.

Dado que este problema afeta diretamente o objetivo principal do seu PR, recomendo fortemente que a implementação do linkedHashMap seja corrigida.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tá certo, a intenção dessa lib é implementar uma estrutura de Conjunto, sem itens repetidos

Comment threadlinkedhashset_test.go Outdated
@fm4teus
fm4teus merged commit e3903aa into StudioSol:masterOct 2, 2025
1 check passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@fm4teus@rodrigofigueiredo005