2015-09-15 9 views
6

Ho un'applicazione CLI che richiede sympy. La velocità dell'applicazione CLI è importante: viene utilizzata molto in un ciclo di feedback dell'utente.C'è un modo per velocizzare un'importazione?

Tuttavia, è sufficiente eseguire import sympyper un secondo intero. Questo diventa incredibilmente fastidioso in un ciclo di feedback serrato. Esiste comunque il "precaricamento" o l'ottimizzazione di un modulo quando uno script viene eseguito di nuovo senza una modifica al modulo?

+1

Sembra che gli sviluppatori di 'sympy' siano a conoscenza di questo problema. C'è un [vecchio bug report] (https://github.com/sympy/sympy/issues/3396), e ci sono anche diversi commenti in ['sympy/__ init __. Py'] (https://github.com/sympy /sympy/blob/master/sympy/__init__.py) che menziona le importazioni lente. Forse presentare un problema di nuovo? (Dopo esserti assicurato di utilizzare la versione più recente) –

+0

Riscrivi la tua applicazione CLI in modo che tu possa eseguirla solo una volta, ma alimentarla con più input diversi ...? – twalberg

+0

@twalberg A quel punto non è più un'applicazione CLI. Per essere più specifici, la mia applicazione è un interprete di lingua. – orlp

risposta

3

Ovviamente sympy fa molto quando viene importato. Potrebbe essere l'inizializzazione di strutture dati interne o simili. Si potrebbe chiamare questo difetto nella progettazione della libreria sympy.

L'unica scelta possibile in questo caso è evitare ripristinare questa inizializzazione.

Suppongo che questo comportamento ti infastidisca perché hai intenzione di farlo spesso. Propongo di evitare di farlo spesso. Un modo per ottenere ciò potrebbe essere quello di creare un server avviato una sola volta, importa sympy all'avvio e quindi offre un servizio (tramite comunicazione tra processi) che consente di fare tutto ciò che si desidera fare con sympy.

Se questa potrebbe essere un'opzione per voi, potrei approfondire su come farlo.

+0

Credo che sarebbe troppo ingegnoso, e piuttosto fragile da rendere multipiattaforma. Non c'è modo di 'snapshot' uno stato dell'interprete (dopo l'importazione) e caricare l'intero stato dell'interprete dal disco? – orlp

+0

Nessuno che io conosca. Sul mio computer vecchio di parecchi anni, btw, ho bisogno solo di una frazione di secondo per importare 'sympy'. – Alfe

+0

* "carica l'intero stato dell'interprete dal disco" * - [ASLR] (https://en.wikipedia.org/wiki/Address_space_layout_randomization) è solo uno dei tanti motivi per cui ciò non funzionerà. –

0

Si dovrebbe verificare se l'importazione solo dei moduli che si stanno utilizzando nel codice migliora il tempo di caricamento.

IE:

from sympy import mod1, mod2, mod3 

vs

import sympy 

Si consiglia di leggere queste domande precedenti:

Python import X or from X import Y? (performance)

improving speed of Python module import

'import module' vs. 'from module import function'

+0

Lo sto già facendo e non fa assolutamente nessuna differenza. – orlp

+0

Hmm ... forse otterrai un risultato migliore usando un server laterale, come Alfe ti ha detto ... –

1

ho preso uno sguardo a cosa succede quando si esegue l'importazione sympy, e importa tutto sympy.

https://github.com/sympy/sympy/blob/master/sympy/__init__.py

Se si utilizzano solo alcune parti del sympy, quindi importare solo quelle parti di cui avete bisogno.

Sarebbe bello se si potesse fare questo:

import sympy.sets 

Ma (come fai notare) che le importazioni sympy e poi imposta.

Una soluzione è scrivere il proprio importatore. Puoi farlo con l'aiuto del modulo imp.

import imp 
sets = imp.load_module("sets", open("sympy/sets/__init__.py"), "sympy/sets/__init__.py", ('.py', 'U', 1)) 

Ma anche questo potrebbe non ottimizzare abbastanza.Dando uno sguardo al sympy/sets/__init__.py vedo che fa questo:

from .sets import (Set, Interval, Union, EmptySet, FiniteSet, ProductSet, 
    Intersection, imageset, Complement, SymmetricDifference) 
from .fancysets import TransformationSet, ImageSet, Range, ComplexRegion 
from .contains import Contains 
from .conditionset import ConditionSet 

Forse è possibile importare solo il modulo imposta da imposta simpy namespace?

import imp 
sets = imp.load_module("sets", open("sympy/sets/set.py") "sympy/sets/set.py", ('.py', 'U', 1)) 
+0

Questo purtroppo non funziona affatto, poiché 'import sympy.sets' da solo eseguirà' sympy/__ init__. py', che importa tutto. – orlp

+0

anzi, mi dispiace. – jrwren

Problemi correlati