Allocazione statica e dinamica della memoria - molti oggetti costanti, solo una piccola parte di essi utilizzati in fase di runtime

1

Ecco due opzioni:

Opzione 1:

enum QuizCategory {

    CATEGORY_1(new MyCollection<Question>()
                    .add(Question.QUESTION_A)
                    .add(Question.QUESTION_B)
                    .add...),

    CATEGORY_2(new MyCollection<Question>()
                    .add(Question.QUESTION_B)
                    .add(Question.QUESTION_C)
                    .add...), 

    ...

    ;

    public MyCollection<Question> collection;

    private QuizCategory(MyCollection<Question> collection) {
        this.collection = collection;
    }

    public Question getRandom() {
        return collection.getRandomQuestion();
    }

}

Opzione 2:

enum QuizCategory2 {

    CATEGORY_1 {

        @Override
        protected MyCollection<Question> populateWithQuestions() {
            return new MyCollection<Question>()
                                .add(Question.QUESTION_A)
                                .add(Question.QUESTION_B)
                                .add...;
        }
    },

    CATEGORY_2 {

        @Override
        protected MyCollection<Question> populateWithQuestions() {
            return new MyCollection<Question>()
                                .add(Question.QUESTION_B)
                                .add(Question.QUESTION_C)
                                .add...;
        }
    };

    public Question getRandom() {
        MyCollection<Question> collection = populateWithQuestions();
        return collection.getRandomQuestion();
    }

    protected abstract MyCollection<Question> populateWithQuestions();

}

Ci saranno circa 1000 categorie, ciascuna contenente 10 - 300 domande (100 in media). Generalmente durante l'esecuzione vengono utilizzate solo 10 categorie e 30 domande. Ogni domanda è di per sé una costante enum (con i suoi campi e metodi).

Sto cercando di decidere tra queste due opzioni nel contesto dell'applicazione mobile. Non ho effettuato alcuna misurazione poiché non ho ancora scritto le domande e vorrei raccogliere più informazioni prima di impegnarmi in una o in un'altra opzione. Per quanto ho capito:

(a) L'opzione 1 funzionerà meglio poiché non sarà necessario popolare la raccolta e quindi raccogliere le domande; (b) L'opzione 1 richiede memoria aggiuntiva: 1000 categorie x 100 domande x 4 byte per ogni riferimento = 400 Kb, che non è significativo.

Quindi mi sto appoggiando all'opzione 1, ma mi chiedo se sono corretto nelle mie ipotesi e non mi manca qualcosa di importante? Forse qualcuno ha affrontato un dilemma simile? O forse non importa così tanto?

    
posta k29 29.06.2013 - 01:09
fonte

2 risposte

1

Se le differenze tra due approcci non sono significative né in runtime né in termini di prestazioni (e significano significati: dal punto di vista degli utenti, non da un punto di vista accademico), quindi scegliere l'approccio che è più facile da implementare e mantenere .

In realtà, vedendo solo quella piccola parte della tua applicazione non posso dirti quale di questi due approcci è più facile da gestire a lungo termine, ma la prima impressione è che "l'Opzione 1" non è solo più veloce, ma sembra anche bisogno di meno codice (a prima vista). Le domande che dovresti porci prima di prendere la decisione finale qui sono:

  • l'estrapolazione della memoria è valida per i prossimi mesi (o anni) quando il programma viene eseguito in produzione?

  • l'elenco di categorie / domande non cambia mai durante il periodo di esecuzione dei programmi? (se può cambiare, ci sarà ovviamente bisogno di ricaricare gli oggetti da qualche parte in un dato momento)

  • quali altre operazioni (oltre a getRandom ) funzionanti con collection saranno necessarie nel tuo programma? Queste operazioni sono più facili da implementare quando si precarica tutto?

Inoltre, fornire un accessore getCollection può essere una buona idea, quindi è possibile nascondere il caricamento / ricarica / caricamento lento nell'implementazione di tale accessorio e modificarlo in seguito, quando necessario. Quindi fallo

    public Question getRandom() {
        return getCollection().getRandomQuestion();
    }

quindi puoi cambiare la tua decisione iniziale in un secondo momento più facilmente.

    
risposta data 29.06.2013 - 09:33
fonte
1

C'è qualche ragione particolare per cui stai caricando dati che sai non saranno utilizzati? Cerca di limitare quelle query / elenchi di caricatori solo ai dati che intendi utilizzare.

Invece di caricare prima l'intero set di dati e poi filtrare, applica la funzione di selezione casuale a un indice / chiave per un set di dati, quindi carica solo quei record particolari con un indice / chiave corrispondente.

Se non si dispone di un indice o di una chiave per eseguire una query e non è possibile aggiungere un indice / chiave in modo longevo, eseguire una trasformazione del set di dati in memoria e aggiungere una chiave sintetica o falsa a ogni , quindi memorizza nella cache i dati trasformati e con chiave. Da lì in poi, fai riferimento ai dati memorizzati nella cache utilizzando la chiave aggiunta, fino a quando la cache non è valida.

    
risposta data 29.06.2013 - 04:22
fonte

Leggi altre domande sui tag