none
Travamento usando o Dictionary com muitos itens ... RRS feed

  • Pergunta

  • Private MyList As Dictionary(Of UInteger, UInteger)

     

            Private Sub FillList()

                MyList = New Dictionary(Of UInteger, UInteger)

               

                    For tb As Integer = 1 To 6000

                      For dCol As Integer = 1 To 130    

                        For dLin As Integer = 1 To 500

     

                            Dim thisNumber As UInteger = MyNumber(dCol, tb, dLin)

     

                            If Not MyList.ContainsKey(thisNumber) Then

                                MyList.Add(thisNumber, thisNumber)

     

                                 RaiseEvent NewNumber(byval tb, dCol, dLin, myList.Count)

     

                                If MyList.Count >= 49000820 Then

                                    Exit Sub

                                End If

     

                            End If

                        Next

                    Next

                Next

            End Sub   

     

     

    No código acima, a função MyNumber retorna um numero que pode variar de 1 a 48.000.820.

    É possível que o mesmo número seja gerado outra vez, em outra iteração.

    O número é adicionado â collection, se já não tiver sido adicionado antes.

    Se a collection for preenchida com todos os números possíveis, a Sub é encerrada.

    Caso contrário, todos os For...Next são executados até o fim.         

    Ao final, vou processar os números armazenados em outra rotina.

     

     

    Pode parecer estranho estar usando Dictionary para armazenar números inteiros, mas é a única Collection em que a velocidade de processamento não diminui â medida que o número de items aumenta.

    ArrayList e List(of T) consumiram tempo demais, testei com os métodos .Contains, IndexOf e .Find.

    Também testei armazenando em DataTable mas a performance foi ainda pior (como eu esperava).

     

    O Dictionary precisa estar aberto na memória para que seja possível verificar "se já tem".

     

    Ficou com velocidade bem satisfatória.

    O problema é que, quando o Dictionary atinge uma determinada quantidade (uns 30 e poucos milhões) a máquina congela. Esperei uns 30 minutos e não liberou.

    Reparei também que, durante a execução, mesmo sendo rápida, se eu apenas mexer o mouse, a máquina congela por alguns segundos e depois retorna.

    Mas no travamento dos 30 e poucos milhões é preciso desligar o micro na marra.

     

    Alguém poderia indicar um modo melhor (= que processe até o fim, sem perder velocidade e sem congelar) de fazer isso?

    P.S: estou rodando de dentro do Visual Studio 2010. O debugger não capta nenhum erro, parece que está processando mas alguma sobrecarga ocorre com o micro

    Processador i7, 8GB RAM  

    Obrigado pelas respostas.




    sábado, 18 de janeiro de 2014 23:51

Respostas

  • Amigo,

    é impossível isso dar certo, nenhum estrutura vai fazer isso funcionar e outra existem máquinas que não vai rodar esse aplicativo pela falta de equipamento ....

    Não é melhor você expor o que você quer fazer a sua regra para gente tentar mudar esse código!!! ???


    Fulvio Cezar Canducci Dias

    segunda-feira, 20 de janeiro de 2014 19:35

Todas as Respostas

  • E não entendi ???

    Fulvio Cezar Canducci Dias

    segunda-feira, 20 de janeiro de 2014 15:33
  • Resumindo:

    Estou usando uma collection tipo Dictionary para armazenar números que vão de um até quase 50 milhões.

     

    O Dictionary tem que estar carregado TODO na memória, porque, antes de armazenar, tenho que pesquisar se já tem, para não armazenar duas vezes o mesmo número.

     

    Testei com diversos modos de armazenamento: List(of T), ArrayList, DataTable e até gravando em BD.

    Em todos eles a pesquisa (para ver se já tem antes de armazenar) fica lenta demais.

    Com o Dictionary, a velocidade ficou perfeita.

     

    O problema: quando o Dictionary está muito grande (cerca de 35.000.000) , em um determinado momento, o sistema pára, e o micro fica "congelado".

    O debugger do VS não interrompe a execução, como acontece quando dá erro de Memory Overflow.

    Parece que continua executando alguma tarefa (talvez redimensionando o Dictionary...) mas demora um tempo enorme ou infinito. Esperei 40 minutos e nada aconteceu, tive que desligar o micro no botão, pois tudo fica congelado.

     

    Preciso de alguma idéia para processar isso de modo eficiente, mesmo que tenha que mudar a lógica do programa.

     

    Obrigado pelas respostas.

    segunda-feira, 20 de janeiro de 2014 18:48
  • Amigo,

    é impossível isso dar certo, nenhum estrutura vai fazer isso funcionar e outra existem máquinas que não vai rodar esse aplicativo pela falta de equipamento ....

    Não é melhor você expor o que você quer fazer a sua regra para gente tentar mudar esse código!!! ???


    Fulvio Cezar Canducci Dias

    segunda-feira, 20 de janeiro de 2014 19:35