Can performance justify such a design choice?
Con così poche informazioni, penso che il consiglio verrà spinto verso suggerimenti di profilazione e misurazione e avvertimenti sull'ottimizzazione prematura. Ma cercherò di darti il beneficio del dubbio.
Applichiamo una mentalità progettuale orientata ai dati che inizia con l'idea della rappresentazione dei dati più ottimale, e ci avvicina alle interfacce da lì. L'aspetto più utile di questo esercizio saranno le interfacce pubbliche che progettiamo, la considerazione delle rappresentazioni dei dati è principalmente quella di garantire un'interfaccia che possa lasciare spazio alle ottimizzazioni senza rotture a cascata nel sistema.
Design orientato ai dati
Since our application is performance critical, instead of copying all
attributes (possibly pointers) of Important that are needed by Small
and redefine the few methods in Small, we decided to just let Small
hold a pointer on Important.
Alcune ipotesi che farò per restringere l'ambito:
- C'è un carico di queste istanze
Small*
.
- La fase di inizializzazione in cui vengono creati come un sottoinsieme di dati
Important's
è separata e al di fuori dei percorsi di codice critici, non interlacciati (altrimenti il tuo suggerimento esistente potrebbe essere il percorso migliore).
- Il percorso critico sta eseguendo un ciclo di caricamento di queste istanze
Small
.
- I campi di
Important
stesso, al di fuori del sottoinsieme rappresentato da Small
, sono freddi.
- I campi di
Important
non cambiano dopo il passo di inizializzazione (le loro punte potrebbero cambiare se ci sono campi puntatore, ma gli indirizzi del puntatore non cambierebbero).
One-to-One
A condizione che esista una relazione uno-a-uno di un sottoinsieme Small*'s
di campi di dati a un Important
(nessuna ridondanza), in genere il modo più veloce è copiare e duplicare effettivamente i dati di Important
in piccolo.
Poiché Important
è dati a freddo in base ai nostri presupposti, che consente a Small
di assumere una natura più contigua e che un numero maggiore dei dati pertinenti si adatti a una riga della cache senza essere mescolato con dati irrilevanti.
Many-to-One
Se ciò è sbagliato e c'è molta risonanza tra Small*
istanze (cioè una relazione molti-a-uno tra Small
riferimenti a un campo Important
), quindi duplicare i dati potrebbe fare più danni che buona.
In tal caso, il puntamento a Important
può iniziare a mostrare un vantaggio favorevole, dato che stiamo giocando a una località temporale con Important
campi spesso seduti in una linea della cache e riducendo Small
in basso alla dimensione di un puntatore singolo.
Per duplicare o non duplicare
Quindi la scelta se duplicare o meno dipende dal livello di ridondanza e se la fase di inizializzazione di un piccolo è al di fuori dei percorsi critici. Se vuoi sapere a quale livello di ridondanza, considera la dimensione totale di tutte le istanze Small*
se quei campi da Important
sono stati duplicati. Se la dimensione non è maggiore della somma di tutti i campi Important
, copiare i campi pertinenti su Small
potrebbe essere una scommessa sicura (a condizione che non sia necessario accedere a Important
nei percorsi critici, che sia veramente freddo dopo quel punto).
Con poca o nessuna ridondanza e Important
a freddo, allora la suddivisione del campo hot / cold in realtà con ridondanza per ottenere il lato caldo della suddivisione può effettivamente aiutare molto (per quanto intuitiva possa sembrare).
Ultimo ma non meno importante, dovrebbe esserci un carico di barca di Small*
istanze istanziate e accessibili. Se non ci sono, allora questo è preoccupante per qualcosa che non dovrebbe essere preoccupato, dato che probabilmente trarrai un vantaggio molto dalla localizzazione temporale in entrambi i casi.