Que tipo de lista dinamica me conviene utilizar?

Iniciado por Skeletron, 8 Febrero 2010, 07:37 AM

0 Miembros y 1 Visitante están viendo este tema.

Skeletron

Hola gente, les comento que acabo de terminar un indexador para un buscador mio (no es un buscador como google)
La cuestion, es que tengo varios hilos que acceden de forma sincronizada (Synklock) a un Generic.coleccion.List(of String)
Dentro del Synklock miro si la cadena que quiero agregar existe (con .Contains) y si no se encuentra, entonces e hago un .add

Cual es el problema? el problema está en que cuando el array comienza a tener unos cuantos millones de Strings (de 10 millones para arriba), la busqueda con el .Contains se pone demasiado LENTA.. y como sarban, eso no es muy bueno que suceda dentro de un Synklock, donde tengo unos 500 hilos por detras esperando para entrar...
El 98% del tiempo los hilos se la pasan esperando ahí para entrar.. ya que tarda demasiado en devolver el resultado el .Contains

Entonces pense en otro tipo de lista.. de esas que no se agregar los items repetidos...
No se bien si existen esas listas en vb.net, pero sé que en JAVA si, porque las utilice (treeset o hashset)

Conocen algun tipo de array de ese tipo, para que simplemente haga un .add y si ya esta el item, que lo borre solo, y si no esta, que lo agregue?

Gracias chicos!

MANULOMM

lo mejor para esto es utilizar un diccionario, y segundo para hacer la busqueda utiliza linq sera mas rapido.
10 millones es un volumen muy alto para tener en memoria, por que no utilzas un repocitorio fisico, te ingenias algo con estadisticas o simplemente utilizas sql para eso... si lo haces en memoria te recomiendo mires LINQ Paralelo pero esto solo es para .net framework 4

Atentamente,

Juan Manuel Lombana
Medellín - Colombia


Skeletron

Gracias manu..
A ver si me asesoras un poco mas con el tema de DIccionarios y LINQ

Te comento Manu, que baje el tamaño maximo del array a 2.000 items.. cuando llega a 2.000 los hilos que trabajan en el "AREA 1", esperan que los de "AREA 2" analicen cada item y baje a menos de 1.000 items, así se reactivan los de "AREA 1"


Me gustaria que me digas como es el tema de los Diccionarios...
Como es la clase a crear?
Los items que se agrean quedan al final? se auto ordenan? no pueden entrar items repetidos? que me dices?

Me gustaria tener como un "LIST" simplemente con el plus de que no se agreguen los items repetidos.. y que se ingresen al final los items al darle add.

Tengo una base de datos MySQL Manu, te comento como funciona el programa:

20 hilos, cada uno agarra un link de la base de datos, descarga su codigo fuente, y agrega nuevamente a la base de datos todos los links a otras webs que encontro en ese codigo fuente..
En realidad.. todos agregan los nuevos links a un array (list), y luego, cuando todos terminan (algo así), se pasan todos a la base de datos (donde muchos no se agregan por estar repetidos)

Tambien los mismos links buscan imagenes.. y agregan a otro list....

Ambos list me gustarian que no tengan ni imagenes ni links repetidas...
Tu me dices que recomiendas un Diccionario?


Y para que dices de utilizar LINQ?

MANULOMM

haber segun entendi estas haciendo un Bot como el de google o algo asi...

envez de crear un List<> creas un Dictionary<string,string> el primer parametro del Diccionario es un indice lo que optimizara tu busqueda. en realidad puede ser de cualquier tipo, el segundo es el tipo de lo que guardas en tu caso el tipo del List<>.

una recomendacion por que no vas consultado y guardando y para evitar que se repitan en la BD utilizas un Indice Unico... asi se llaman en SQL Server nose en MySQL como se llamaran.

Atentamente,

Juan Manuel Lombana
Medellín - Colombia


seba123neo

pregunta ¿ para que descargas el codigo fuente ?
La característica extraordinaria de las leyes de la física es que se aplican en todos lados, sea que tú elijas o no creer en ellas. Lo bueno de las ciencias es que siempre tienen la verdad, quieras creerla o no.

Neil deGrasse Tyson

Skeletron

Manu, obviamente que las ingreso a una base de datos, con clave unica.. Pero para agilizar el procesamiento y demas, hago el traspaso del array: "LinksNuevos" una vez que se hayan procesado 50 webs.. Así evito miles y miles de entradas a la abse de datos...
Por el tema de que una E/S, es muy muchisimo mas lenta que una comprobacion si esta o no esta una cadena dentro de un array..

Sebas, te respondo:
Descargo el codigo fuente de cada web para analizarle sus links, y así sucesivamente.

Skeletron

Y Manu, no hay manera de crear un diccionario de ese tipo, pero sin la clave? porque, no se ni que ponerle, no utilizaré la 1º clave.

Probaré hoy.. Pero: ¿Dictionary, no acepta entradas duplicadas?

MANULOMM

la clave seria por ejemplo un GUID o un HASH apartir de la cadena, o la misma cadena asi no podras tener indices repetidos,  pero pensandolo bien solo guardas la cadena... asi que seria lo mismo.....

haber si entendi bien.
entras a una web descargas su codigo fuente analisas los vinculos y los guardas.... yo lo haria todo contra la bd, al fin y al cabo las entradas multiples a la BD el motor de la misma las controla con hilos. o por lo menos asi es en SQL.

No logro entender por que utilizas esas listas tan exageradamente grandes.

Atentamente,

Juan Manuel Lombana
Medellín - Colombia


Skeletron

Por ésto:
supongamos que 500 hilos estan procesando al mismo tiempo 500 post diferentes de este foro.
Los 500 post, tienen un link a: foro.elhacker.net, ya que es el link que tiene la imagen de logo de arriba de todo...

Los 500 hilos crearian un flujo de 500 entradas al servidor MySQL que lo tengo en un HOSTING.

Pero, si antes de pasarlo directamente a la base de datos, lo meto en una lista donde no hay items repetidos, entonces, los 500 hilos agregarian a la lista aqui en la PC el link foro.elhacker.net, y en realidad, habría solo 1 item en la lista, ya que 499 estuvieron repetidos... al terminar el procesamiento de todos los hilos, otro hilo se encarga de meter todo lo que habia en la lista de links a la base de datos, y solo haría 1 solo INSERT... en vez de 500 :)

Entendiste tio? :D

Skeletron

Por lo que veo:
Código (vbnet) [Seleccionar]
Dim lista As New Dictionary(Of String, String)
        lista.Add("noel", "noel")
        lista.Add("noel", "asdasd")
        lista.Add("asd", "noel")
        lista.Add("noel", "noel")


Al ingresar la 2º entrada, con la misma clave, da un ArgumentException.
Tardó mucho en "avisarme" el depurador del error (como 1 segundo)...
Si tarda mucho, tendria que seguir con el "if not lista.Contains then lista.add()"

Que me recomiendas Manu?