Come presentare rapidamente migliaia di immagini in una jlist

0

Ho bisogno di opinioni sulle persone su come migliorare un codice che ho scritto. Supponiamo di avere un'applicazione di catalogazione di film (~ 3500 di essi) e attori (~ 1000, ma ho bisogno di ricontrollare questo).

Sia gli attori che i film sono POJO. Un attore ha un'immagine, memorizzata su disco e il suo percorso in un database, insieme alla persona altri attributi. Un film ha una serie di attori e altri attributi POJO.

Dato un film, devo essere in grado di selezionare gli attori che ci giocano. Ho quindi creato una jlist con un'immagine bufferizzata ridimensionata dell'immagine degli attori. Questa jlist è molto utilizzata attraverso l'app. E i problemi sono con le prestazioni del popolamento di questa jlist. Ci vuole un po 'di tempo per creare tutti gli oggetti personali e caricare le loro immagini (~ 2 minuti) e questo distrugge l'usabilità. Il collo di bottiglia al momento è l'IO del disco nella lettura dell'immagine. Ho passato diverse iterazioni, ma l'ultima è la seguente:

  • All'avvio, passa in rassegna la tabella delle persone e crea tutti gli oggetti persona con attributi accessibili direttamente nel DB.
  • Passa in rassegna la collezione di oggetti persona di cui sopra e, per ognuno, ottieni la sua immagine e le sue immagini bufferizzate (che vengono utilizzate in diversi contesti, l'immagine bufferizzata viene usata molto più spesso) e le aggiungi come attributi. Le immagini sono su disco.
  • Restituisce l'arraylist sincronizzato sopra al livello applicazione e lo usa come cache.

Ci sono poche differenze tra ottenere gli attributi e le immagini nello stesso ciclo (almeno in termini di prestazioni). Con questo approccio, devo aspettare i 2 minuti per creare tutti gli oggetti prima di iniziare a usare l'app. Ma usare la jlist è super veloce perché ho solo bisogno di accedere alla cache. Ma mi piacerebbe ridurre il tempo di attesa per caricare l'app. Capisco che non c'è molto che possa essere fatto per migliorare l'accesso al disco, ma forse è possibile un approccio migliore.

Questa è un'applicazione java con swing e sqlite. Posso condividere parte del codice se aiuta a chiarire la domanda.

    
posta Sandrew Cheru 31.05.2017 - 18:42
fonte

1 risposta

1

Puoi usare un ListModel per restituire valori segnaposto fino a quando le cose non vengono caricate. All'avvio si caricano e si memorizzano solo le prime decine di cache. quindi quando viene richiesto il valore per attivare un'attività utilizzando SwingWorker in esecuzione in un thread in background.

public class BackgroundLoader extends SwingWorker<Void, Person>{

    private LinkedBlockingQueue<ID> queue = new LinkedBlockingQueue<>();
    private MyListModel list;

    //runs in background -> not safe to access ListModel
    public Void doInBackground(){

        while(true){
            ID id = queue.take();
            Person person = PersonDB.load(id);
            publish(person);
        }
    }

    //runs in swing event thread -> safe to access ListModel
    public void process(List<V> chunks){
        list.addPersons(chunks);
    }

    public void startLoad(ID id){
        queue.put(id);
    }

}

Allo stesso modo non caricare le immagini in anticipo. Quando hai bisogno di un'immagine, restituisci un segnaposto e invia uno SwingWorker per caricare l'immagine reale.

    
risposta data 01.06.2017 - 12:11
fonte

Leggi altre domande sui tag