Wrapping istruzione semplice in una funzione in java?

3

Stavo lavorando al database grafico neo4j in java. Per ottenere il nodo di riferimento di questo db:

    GraphDatabaseService graphDb=new EmbeddedGraphDatabase(DB_PATH);

    Node Root=graphDb.getReferenceNode()

Mi dimentico sempre di anteporre graphDb quando chiami getReferenceNode (). Quindi cosa ho fatto:

   public Node getRootNode(){
   return graphDb.getReferenceNode(); }

Ora, dopo averlo fatto, ho pensato che fosse eccessivo poiché sto sostituendo una semplice istruzione con una chiamata di funzione che sicuramente ha un overhead ma usare getRootNode mi sembra più intuitivo.

Quindi la mia domanda è che ho ragione nel pensare che fare la cosa sopra menzionata è inefficiente? O non influisce molto sulle prestazioni?

    
posta codecool 19.07.2011 - 09:49
fonte

8 risposte

2

Puoi anche solo memorizzare il referenceNode in una variabile poiché è costante per GraphDatabaseService .

Puoi anche dichiararlo come variabile di istanza final nel costruttore del tuo servizio per documentarlo.

    
risposta data 19.07.2011 - 11:00
fonte
8

Nella moderna Java, le chiamate di funzione sono praticamente gratuite. Se viene chiamato raramente, non si noterà il sovraccarico. Se viene chiamato frequentemente, la JIT effettuerà la chiamata in linea, eliminando eventuali spese generali.

    
risposta data 19.07.2011 - 10:10
fonte
3

Pensaci ancora.

1. YAGNI - Non ne avrai bisogno. Hai davvero bisogno di avvolgere la funzione? Con quale frequenza e in quanti posti risolvi un nodo radice e, cosa più importante, prevedi di aggiungere un ulteriore comportamento a questo metodo in seguito?

2. Migliora davvero la leggibilità? Questo è altamente soggettivo. Ai miei occhi, entrambe le varianti sono quasi uguali nella leggibilità. Preferirei anche il primo se non avessi davvero bisogno del wrapper perché non voglio aggiungere un comportamento in seguito, poiché è più facile eseguire il debug, un livello in meno da eseguire.

3. Prestazioni Questa è una preoccupazione minore qui. Dubito che tu lo chiami molto spesso. Quando lo chiamate in un ciclo, potrebbe avere un strong impatto sulle prestazioni. L'overhead è trascurabile per le chiamate a singola funzione.

4. Decisione di progettazione Vuoi nascondere completamente il membro graphDB, cioè dietro un'interfaccia? Quindi con tutti i mezzi crea un'intera astrazione di esso con tutti i metodi necessari.

Detto questo, l'aumento della leggibilità è altamente soggettivo (solo ai tuoi occhi) mentre si aggiunge un nuovo livello che potrebbe potenzialmente portare a una perdita di prestazioni. Va bene se hai bisogno di quel wrapper perché ti aspetti di aggiungere un ulteriore comportamento in seguito e il tuo codice è cosparsa di chiamate di getReferenceNode() . Se hai solo una singola chiamata o pochissime chiamate di getReferenceNode e non prevedi di aggiungere ulteriori comportamenti in seguito, non creerò quel wrapper.

    
risposta data 19.07.2011 - 10:00
fonte
3

Un classico esempio di ottimizzazione prematura. Quando scrivi il codice devi sentirti libero di aggiungere tutta la struttura che ritieni più adatta. Successivamente, un profiler ti dirà dove è necessario ottimizzare.

    
risposta data 19.07.2011 - 10:53
fonte
1

Utilizza un profiler per verificarlo. A volte, è meglio aumentare la leggibilità se non c'è una penalizzazione delle prestazioni così grande.

    
risposta data 19.07.2011 - 09:52
fonte
1

Questo mi sembra l'equivalente Java della creazione di una macro C / C ++ per salvare digitando alcune lettere, che non posso accettare come buona pratica. Ricontrollerai il codice molto più spesso di quanto lo scriveresti, quindi il "livello aggiuntivo di riferimento indiretto" che hai aggiunto avrà un costo molto maggiore in termini di manutenzione rispetto a quanto potresti risparmiare nello sviluppo.

    
risposta data 19.07.2011 - 15:47
fonte
0

SO my question is am i right in thinking that doing above mentioned thing is inefficient? or it does not affect performance that much?

Se si è maggiormente preoccupati per le prestazioni, inserire ciascuna variante in un ciclo separato, eseguirla per un milione o più volte e misurare la differenza di tempo tra l'esecuzione delle due varianti. Le probabilità sono che la differenza sarà trascurabile a inesistente.

Se si guarda il codice byte, non sarei affatto sorpreso se l'intera funzione è delineata dal compilatore, poiché tutto ciò che fa è racchiudere un'altra chiamata.

    
risposta data 19.07.2011 - 10:27
fonte
0

Non farlo. Stai semplicemente rinominando la funzione per adattarla ai tuoi preconcetti personali. Alcuni futuri manutentori dovranno imparare neo4j e conosceranno il significato di getReferenceNode . Quindi vedrà le chiamate a getRootNode e penserà "getRootNode? WTF è?" Poi andrà a leggere la tua funzione, e afferrare qualcosa e lanciarla contro il muro imprecando contro il tuo nome. Quindi eseguirà il refactoring, eliminando getRootNode .

Introduciamo funzioni per ridurre i costi di duplicazione e manutenzione. La tua funzione fa il contrario.

Qualcuno ha fatto una scelta per usare neo4j. Impara e usalo come progettato.

    
risposta data 19.07.2011 - 18:47
fonte

Leggi altre domande sui tag