Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@fm4teus
Copy link
Member

@fm4teus fm4teus commented Oct 1, 2025

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

N Caso Contains (ns/op) InArray (ns/op) Contains (B/op) InArray (B/op)
20000 Found 159.0 1,300,429 24 491,804
20000 NotFound 242.6 1,782,240 40 491,781
40000 Found 155.8 2,409,341 24 975,117
40000 NotFound 225.8 3,536,619 40 975,124
60000 Found 186.4 4,663,344 24 1,450,258
60000 NotFound 239.0 6,492,405 40 1,450,237
80000 Found 160.5 5,832,141 24 1,933,580
80000 NotFound 264.6 8,301,901 40 1,933,565
100000 Found 163.2 7,531,702 24 2,408,700
100000 NotFound 236.5 10,035,038 40 2,408,730
image image
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

@fm4teus fm4teus self-assigned this Oct 1, 2025
@gemini-code-assist
Copy link

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.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays 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.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

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 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

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
Member Author

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

@fm4teus fm4teus merged commit e3903aa into StudioSol:master Oct 2, 2025
1 check passed
Sign up for free to 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