Aggiungo solo qualcosa per l'opzione "altre lingue".
C: Dato che questo è solo un esercizio accademico che non fa davvero differenza, ho pensato di contribuire con qualcosa di diverso.
Ho compilato in assembly senza ottimizzazioni e ho guardato il risultato.
Il codice:
int main() {
volatile int a;
volatile int b;
asm("## 5/2\n");
a = 5;
a = a / 2;
asm("## 5*0.5");
b = 5;
b = b * 0.5;
asm("## done");
return a + b;
}
compilato con gcc tdiv.c -O1 -o tdiv.s -S
la divisione per 2:
movl $5, -4(%ebp)
movl -4(%ebp), %eax
movl %eax, %edx
shrl $31, %edx
addl %edx, %eax
sarl %eax
movl %eax, -4(%ebp)
e la moltiplicazione per 0,5:
movl $5, -8(%ebp)
movl -8(%ebp), %eax
pushl %eax
fildl (%esp)
leal 4(%esp), %esp
fmuls LC0
fnstcw -10(%ebp)
movzwl -10(%ebp), %eax
orw $3072, %ax
movw %ax, -12(%ebp)
fldcw -12(%ebp)
fistpl -16(%ebp)
fldcw -10(%ebp)
movl -16(%ebp), %eax
movl %eax, -8(%ebp)
Tuttavia, quando ho cambiato quelle int
s in double
s (che è quello che probabilmente farebbe Python), ho ottenuto questo:
divisione:
flds LC0
fstl -8(%ebp)
fldl -8(%ebp)
flds LC1
fmul %st, %st(1)
fxch %st(1)
fstpl -8(%ebp)
fxch %st(1)
moltiplicazione:
fstpl -16(%ebp)
fldl -16(%ebp)
fmulp %st, %st(1)
fstpl -16(%ebp)
Non ho confrontato nessuno di questo codice, ma solo esaminando il codice puoi vedere che usando i numeri interi, la divisione per 2 è più breve della moltiplicazione per 2. Usando i doppi, la moltiplicazione è più breve perché il compilatore usa i codici operativi a virgola mobile del processore, che probabilmente funzionano più velocemente (ma in realtà non lo so) rispetto a non usarli per la stessa operazione. Quindi, alla fine, questa risposta ha dimostrato che le prestazioni della multiplazione per 0,5 rispetto alla divisione per 2 dipendono dall'implementazione del linguaggio e dalla piattaforma su cui gira. In definitiva la differenza è trascurabile ed è qualcosa di cui non dovresti praticamente mai preoccuparti, tranne in termini di leggibilità.
Come nota a margine, puoi vedere che nel mio programma main()
ritorna a + b
. Quando tolgo la parola chiave volatile, non indovinerai mai come appare l'assembly (esclusa l'impostazione del programma):
## 5/2
## 5*0.5
## done
movl $5, %eax
leave
ret
ha fatto sia la divisione, la moltiplicazione E l'addizione in un'unica istruzione! Chiaramente non devi preoccuparti di questo se l'ottimizzatore è rispettabile.
Scusa per la risposta troppo lunga.