HW2 - velocizzare il programma

G
Gioele (280 points)
1 2 3
asked Oct 25, 2020 in HW2 obbligatorio by Gioele (280 points)
recategorized Nov 5, 2020 by andrea.sterbini
Salve! Vorrei chiedervi una mano su l'HW2 riguardo le tempistiche e dove poter efficientare il programma.

Ho usato dizionari e il programma fa uso di soli 2 cicli: uno per calcolare i punti della parola, l'altro più grande per ciclare i turni e calcolare le mani (le lettere da dare al giocatore).

Nonostante questo non riesco a passare gli ultimi 4 test per il tempo.

Dove dovrei implementare l'efficienza? Nel ciclo dei punti uso un solo ciclo ed è il massimo che sono riuscito ad ottenere, riguardo al calcolo delle lettere nella mano,

esiste un modo più efficiente che fare ogni turno?

Vi ringrazio per l'eventuale risposta
308 views

3 Answers

Best answer
Romitoskj (8920 points)
4 8 40
answered Oct 25, 2020 by Romitoskj (8,920 points)
selected Oct 25, 2020 by Gioele
Il tuo algoritmo sembra simile al mio che i test li passa tutti... hai testato solo sul tuo pc o l'hai caricato qui? perché ad esempio una mia vecchia non mi passava gli ultimi due test sul mio pc ma sulla piattaforma li passava tutti.

Comunque se non vado errato i pochi millisecondi che il test impiega oltre il timeout non sono nient'altro che il tempo utilizzato per fermare il codice, non il tempo effettivo in cui viene svolto il test.

In ogni caso prova a dividere il programma in più funzioni, magari il tempo non diminuirà ma il codice sarà più leggibile e avrai una minore complessità ciclomatica.
G
Gioele (280 points)
1 2 3
commented Oct 25, 2020 by Gioele (280 points)
l'ho testato anche qui e non mi passa comunque gli ultimi 4 test. Non so se per errori di ritorno, ma penso di no visto che passo tutto gli altri e mi dice che i 4 rimanenti li ha bloccati per il tempo... infatti molti mi hanno detto che hanno fatto così e nonostante l'implementazione di dizionari e semplificazioni di cicli non passo. Non capisco proprio perché
Romitoskj (8920 points)
4 8 40
commented Oct 25, 2020 by Romitoskj (8,920 points)
L'unica cosa che ti posso consigliare, non sapendo com'è fatto il tuo codice, è di provare a utilizzare il line profiler per vedere quali sono le istruzioni più dispendiose e cercare di sostituirle. Ad esempio io ho diminuito di molto i tempi semplicemente puntando alle parole da calcolare rispetto a prima dove eliminavo ogni volta la parola giocata. Difatti l'eliminazione in se non è molto onerosa però nei test più lunghi occupa una bella fetta di tempo!
G
Gioele (280 points)
1 2 3
commented Oct 25, 2020 by Gioele (280 points)
ecco questo penso sia il mio problema. Elimino la parola che ho usato. Provo a usare altri metodi....Ma poi dovrei fare altri cicli per avanzare con le parole.
Romitoskj (8920 points)
4 8 40
commented Oct 25, 2020 by Romitoskj (8,920 points)
Non per forza! prova a tenere aggiornati contatori che indicano il giocatore ed il turno della partita, puoi riuscire a farlo anche direttamente nel ciclo che già fai, te lo assicuro.
G
Gioele (280 points)
1 2 3
commented Oct 25, 2020 by Gioele (280 points)
Grazie HO RISOLTO!! Era quello! Ci avevo pensato ma non davo troppa importanza! DAJE
Romitoskj (8920 points)
4 8 40
commented Oct 25, 2020 by Romitoskj (8,920 points)
Daje!

Neanch'io inizialmente gli avevo dato tutta questa importanza, ma utilizzando il profiler e vedendo che era un'istruzione fra le più dispendiose (se pur poco con piccoli test) ho provato a levarla, infatti nei test grossi fa moooolta differenza.

E' stato un piacere aiutarti!

(ricorda di settare il post come risolto)
G
Gioele (280 points)
1 2 3
commented Oct 25, 2020 by Gioele (280 points)
e come se setta in quel modo? ahahah
Romitoskj (8920 points)
4 8 40
commented Oct 25, 2020 by Romitoskj (8,920 points)
Ci dovrebbe essere un lucchetto in basso a destra rispetto alla domanda ahahha
michelescara (1330 points)
0 2 6
answered Oct 25, 2020 by michelescara (1,330 points)
edited Oct 25, 2020 by michelescara
Se non l'hai già fatto, prova a spezzare in una funzione il calcolo dei punti. Inoltre controlla se caricando l'homework riesci a passare i test. Anche io sul mio pc non passo due test, ma sul computer del professore li passo tutti con un tempo decisamente migliore di quello che ho riscontrato sul mio.

EDIT:

Anche io ho utilizzato un dizionario per abbassare la complessità ciclomatica, ma ho notato che il tempo di esecuzione è leggermente maggiore rispetto agli if annidati. Non so quanto tempo possa farti guadagnare, ma potresti provare a vedere se con gli if annidati l'efficienza migliori un pochino.
G
Gioele (280 points)
1 2 3
commented Oct 25, 2020 by Gioele (280 points)
fatto anche quello ma non cambia molto. Forse dipende da come gestisco i turni e alterno i giocatori. Avevo provato a mettere tutte funzioni ma senza successo
michelescara (1330 points)
0 2 6
commented Oct 25, 2020 by michelescara (1,330 points)
Allora prova ad eseguire i test senza timeout, e vedi di quanto sforano i test che non riuscivi a passare con il timeout. Se sfori di poco puoi provare a mettere in delle variabili i calcoli che fai più spesso, altrimenti devi rivedere il tuo algoritmo.
G
Gioele (280 points)
1 2 3
commented Oct 25, 2020 by Gioele (280 points)
su Anaconda prompt qual è il comando per fare i test senza avere il timeout? E come faccio a dirgli di fare gli ultimi test? (Grazie ancora per le risposte!!)
michelescara (1330 points)
0 2 6
commented Oct 25, 2020 by michelescara (1,330 points)
Prima devi aprire il file test_01.py e impostare DEBUG=True. Poi utilizzi questo comando:  pytest test_01.py -vv -rA --timeout 1 --durations 0  . Come timeout puoi mettere il valore che vuoi.
Romitoskj (8920 points)
4 8 40
commented Oct 25, 2020 by Romitoskj (8,920 points)

Il comando per eliminare il timeout è "pytest test_01.py -v -rA", ricorda però che di impostare la variabile DEBUG  a True nel file test_01.py altrimenti il comando i timeout non saranno modificabili.

Purtroppo questa cosa non è scritta nelle istruzioni, ti allego qui il post dove è stata detta.

G
Gioele (280 points)
1 2 3
commented Oct 25, 2020 by Gioele (280 points)
Fatto. Li passo tutti, eccetto per il tempo che sfora. Grazie! Cerco di vedere se devo cambiare l'approccio con le turnazioni
Romitoskj (8920 points)
4 8 40
commented Oct 25, 2020 by Romitoskj (8,920 points)

Dai ora che sai di restituire i giusti risultati non ti resta che sbatterci la testa per diminuire il tempo di esecuzione, ma nulla di impossibile. Buona fortuna!wink

G
Gioele (280 points)
1 2 3
commented Oct 25, 2020 by Gioele (280 points)
Grazie mille veramente !!!! Spero di risolverlo
g
giacomo_venturini (6680 points)
2 5 39
answered Oct 25, 2020 by giacomo_venturini (6,680 points)
Prova a ottimizzare i cicli, ragiona su quali verifiche è necessario siano fatte in un certo ordine e quali sono svincolate, e soprattutto verifica di ottimizzare i confronti tra collezioni con numero di elementi differente, privilegiando ciclare su quelle con cardinalità inferiore
G
Gioele (280 points)
1 2 3
commented Oct 25, 2020 by Gioele (280 points)
I cicli sono ottimizzati al massimo, il minimo indispensabile per poter fare i calcoli corretti e per i valori uso un dizionario. Forse dipende da come gestisco le turnazioni: perché ogni volta tolgo la prima parola usando l[1:], così che non devo fare ulteriori cicli per vedere le parole, quindi con un operazione distruttiva. Può essere quello?
g
giacomo_venturini (6680 points)
2 5 39
commented Oct 25, 2020 by giacomo_venturini (6,680 points)
non ho ben capito cosa intendi col togliere la prima parola, nel senso che se sei al turno x togli le parole precedenti che hai già verificato? nel qual caso potresti anche usare un indice, ma non credo sia quello il problema sulle prestazioni