Ver Mensaje Individual
  #8  
Antiguo 05-03-2013
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.939
Reputación: 27
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
Bueno, el problema es que obviamente cargar 2000 imagenes sequencialmente + sincronico va ser lento, y traga cpu y memoria. El asunto es como evitarlo.

Hay 2 cosas que son la causa de la lentitud.

1- Sequencial. Para acelerar un proceso sequencial, lo debes hacer es volverlo asincrónico y/o paralelo. Lo que describes se paraleliza facil porque la imagen N+1 no depende de la imagen previa N ni de la imagen N+2. Para esto, uso de threads y/o liberia asincronica con threads verdes o corutinas

Eso es lo que parece mas obvio, pero el dia que cargues 100.000 imagenes la PC se va a morir.

2- Lo mejor, es solo cargar lo que es necesario para que el usuario visualize las imagenes, pero no mas. Eso se llama un "stream" o una fuente de datos "virtual".

El ejemplo mas popular ahora es lo que se usa en iOS:

http://developer.apple.com/library/i...ViewDataSource

Lo que se hace es que en vez de cargar TODOS los datos en una estructura, se carga solos N necesarios (mas un poquito mas para que no haya un parpadeo al desplazarse con scroll) y se van reciclando las estructuras en la medida que vayan cargandose las cosas. Si buscas como se usa un UITableViewController en tutoriales de iOS veras el esquema, pero te lo voy a poner en seuodocodigo:

El truco se parte, al menos, en 2 partes.

Primero, debes usar un "Record Count" que puede ser totalmente inventado o real. Luego solicitas el "registro" numero N. Ese registro lo buscas en una cola (o matriz o lista). Si esta, lo devuelves, sino, lo cargas de donde sea que este el verdadero registro.

Esto significa que debes recordar en cual registro vas.

O sea:

Código:
function AltoVisualizacion:
  //Aqui calculas el alto de la celda o fila, o de la foto o lo que sea. Si es estatico retornas un #, sino debes llamarlo luego de retornar la imagen y consultar su alto
  return 100

function TotalImages:
    return 1000000 //De alguna manera averiguaste el total. O pones un numero alto pa arrancar, y progresivamente mientras avanzas creces el totalimagenes hasta que te das cuenta que no hay mas...

function RetornarImagen:(posicion:Int):
   img = nil
   imgCtrl = nil

   llaveControl = 'Imagen' //Si tienes varios tipos de visualizadores, un diccionario con cada uno.

   if llaveControl in ListaCache:
     imgCtrl = ListaCache[llaveControl] //Este es el control que muestra la imagen, no la imagen en si
   else
    imgCtrl = CrearControlImagen();
    ListaCache[llaveControl] = img

   img = CargarImagenAhoraSiEnSerio(posicion)

   return img
Una variacion que simplifica la cosa, si puedes obtener la lista de archivos a ver muy rapido (que es lo que parece) es meter en un array o hastable la info de los archivos y usarlo como apuntadores al dato real:

Código:
function AltoVisualizacion:
  //Aqui calculas el alto de la celda o fila, o de la foto o lo que sea. Si es estatico retornas un #, sino debes llamarlo luego de retornar la imagen y consultar su alto
  return 100

function TotalImages:
    return ListaArchivos.Count()

function RetornarImagen:(posicion:Int):
   img = nil
   imgCtrl = nil

   llaveControl = 'Imagen' //Si tienes varios tipos de visualizadores, un diccionario con cada uno.

   if llaveControl in ListaCache:
     imgCtrl = ListaCache[llaveControl] //Este es el control que muestra la imagen, no la imagen en si
   else
    imgCtrl = CrearControlImagen();
    ListaCache[llaveControl] = img

   img = CargarImagenAhoraSiEnSerio(ListaArchivos[posicion])

   return img
La ultima cosa es si la imagen es lenta de cargar. Uniendo a lo anterior, se peude colocar una imagen "temporal", se carga la real de forma asincronica, y se cambia la temporal por la real cuando esta lista. Asi es posible incluso cargar imagenes desde internet.

Eso se enlaza con el control que llama la fuente de datos virtual para alimentarse. Con este esquema, no importa si son 1 o un millon, el gasto d ememoria y CPU nunca sera mayor a AltoVisualizacion() * AltoDeLaVentana() + ImagenesPrecargadasExtra.

Este esquema es la razon principal por la que en iOS se pueden visualizar miles o millones de registro, super rapido, super eficiente en maquinas menos potentes que un desktop. Cuando lo aprendi, me di cuenta de lo idiota que es el modelo de todos los demas lenguajes y frameworks
__________________
El malabarista.

Última edición por mamcx fecha: 05-03-2013 a las 00:05:59.
Responder Con Cita