Velocità di lettura di un codice

di il
11 risposte

Velocità di lettura di un codice

Salve a tutti,
volevo porre una domanda che probabilmente sarà piuttosto banale, tuttavia sono alle prime armi con la programmazione e ne so ben poco...
da cosa dipende la velocità con cui viene letto un codice sorgente?
Ho valutato che il mio pc impiega circa 7 secondi nel leggere un codice contenente 1 miliardo di cicli for.. c'è qualche possibilità di aumentare la velocità di lettura?
Ringrazio e mi scuso ancora per l'ingenuità della domanda

11 Risposte

  • Re: Velocità di lettura di un codice

    Hev87 ha scritto:


    Salve a tutti,
    volevo porre una domanda che probabilmente sarà piuttosto banale, tuttavia sono alle prime armi con la programmazione e ne so ben poco...
    da cosa dipende la velocità con cui viene letto un codice sorgente?
    Ho valutato che il mio pc impiega circa 7 secondi nel leggere un codice contenente 1 miliardo di cicli for.. c'è qualche possibilità di aumentare la velocità di lettura?
    Ringrazio e mi scuso ancora per l'ingenuità della domanda
    Se parliamo di un determinato codice gia scritto, la velocita di lettura puo dipendere dall'hardware presente sulla macchina.

    Se parliamo di scrivere codice , la velocita di esecuzione puo dipendere dal fatto se si usano tecniche di ottimizzazione degli algoritmi o meno.
  • Re: Velocità di lettura di un codice

    Hev87 ha scritto:


    Salve a tutti,
    volevo porre una domanda che probabilmente sarà piuttosto banale, tuttavia sono alle prime armi con la programmazione e ne so ben poco...
    da cosa dipende la velocità con cui viene letto un codice sorgente?
    Ho valutato che il mio pc impiega circa 7 secondi nel leggere un codice contenente 1 miliardo di cicli for.. c'è qualche possibilità di aumentare la velocità di lettura?
    Ringrazio e mi scuso ancora per l'ingenuità della domanda
    Scusa, ma la domanda cosi' come e' posta, non e' comprensibile.

    Che cosa intendi con "velocita' con cui viene letto un codice sorgente"?
    Letto da chi?
    Parli di "leggere un codice contenente 1 miliardo di cicli for..".
    Intendi leggere o eseguire?

    Poi chiedi: "c'è qualche possibilità di aumentare la velocità di lettura".
    Certo che c'e', di sicuro, ma intanto chiarisciti che cosa intendi con "velocita' di lettura".

    Un codice sorgente, dove per 'sorgente' si intende un programma scritto da un programmatore o comunque leggibile da un essere umano, viene "letto" ed "interpretato", oppure "compilato" ed "eseguito".

    Tu parli del processo di lettura prima dell'interpretazione/compilazione o di "interpretazione"/esecuzione?

    Riassumendo:

    = se e' un problema legato alla lettura dal supporto magnetico -> usa un SSD
    = se e' un problema di lettura da parte dall'interprete o di compilazione -> usa un PC piu' veloce
    = se e' un problema di interpretazione/esecuzione -> usa un PC piu' veloce.

    Ma non solo. Se e' un problema di esecuzione, un modo per aumentare le performance dell'applicazione e' quella di usare algoritmi piu' efficienti, oppure strutture dati di supporto.

    Il concetto fondamentale alla base e' il seguente:

    = mai fare due o piu' volte la stessa cosa,
    = non fare qualcosa se non e' strettamente neccessario.

    Ma ce ne sono altri metodi, piu' sofisticati, che richiedono che il programma abbia certe caratteristiche.

    Quindi, in generale, se un programma e' lento, c'e' sempre modo di renderlo piu' efficiente.
  • Re: Velocità di lettura di un codice

    Vi ringrazio per le vostre risposte.

    Come avrete notato, sono piuttosto ignorante in campo di programmazione e capiterà spesso, almeno per i primi tempi, sentirmi adottare termini inadeguati e difficilmente comprensibili.
    Ho provato ad informarmi sul web prendendo come spunto le indicazioni contenute nelle vostre risposte, tuttavia l'unico risultato che ottengo è un allucinante mal di testa dopo aver tentato invano di comprendere il linguaggio tecnico con cui si esprimono gli esperti
    Leggendo le vostre risposte ho capito che ciò che malamente definivo "velocità di lettura" è in realtà la velocità di esecuzione.
    Scrivendo un codice del genere ad esempio:

    static void Main()
    { DateTime Beg = DateTime.Now;
    for (z = 0; z < 1000000000; z++)
    {
    n++;
    }
    DateTime End = DateTime.Now;

    Console.WriteLine(" tempo impiegato = {1} ", End-Beg);
    Console.ReadLine();
    }

    L'Output sarà " tempo impiegato = 00:00:06.199488 ";

    L'obiettivo è ridurre il più possibile quel "06"...
    migliorabile, dicevi che è possibile incrementare la velocità d'esecuzione tramite strutture dati di supporto. Cosa sarebbero di preciso queste strutture? Come si realizzano?

    Ringrazio per la disponibilità e la pazienza
  • Re: Velocità di lettura di un codice

    Se vuoi andare più veloce basta che sostituisco il ciclo con:
    n = 1000000000;
    Ottieni un codice che fa la stessa cosa in meno tempo

    Sembra una battuta perché il codice è molto semplice, però il concetto e quello di usare un algoritmo migliore.
  • Re: Velocità di lettura di un codice

    bartig ha scritto:


    Se vuoi andare più veloce basta che sostituisco il ciclo con:
    n = 1000000000;
    Ottieni un codice che fa la stessa cosa in meno tempo

    Sembra una battuta perché il codice è molto semplice, però il concetto e quello di usare un algoritmo migliore.
    Idea eccellente
    Anche se mi sembrava chiaro che il ciclo for da 1miliardo di ripercussioni serviva esclusivamente come esempio.
    Poco mi interessa sapere quanto fa 1*1miliardo
    Ipotizzando che il nostro codice sia sintatticamente efficiente, quali sono gli ulteriori accorgimenti
    che potrebbero velocizzarne l'esecuzione?
  • Re: Velocità di lettura di un codice

    Non esiste una regola o una bacchetta magica.
    Bisogna valutare caso per caso.
    Ovvio poi che una perfetta padronanza del linguaggio aiuta nel scrivere codice ottimizzato fin dalla prima riga di codice.
  • Re: Velocità di lettura di un codice

    Hev87 ha scritto:


    Ipotizzando che il nostro codice sia sintatticamente efficiente, quali sono gli ulteriori accorgimenti che potrebbero velocizzarne l'esecuzione?
    Ok, se il codice lo consideriamo perfetto dal punto della sintassi e/o non lo vogliamo modificare, a questo punto dipende da cosa succede a questo codice, potrebbe essere convertito in linguaggio macchina da un compilatore (ad es C++) o essere eseguito da una macchina virtuale (Java, C#). In ogni caso diventa importante la bontà del compilatore o dell' interprete.

    I compilatori ottimizzano il codice, ve ne sono di più o meno buoni, ad esempio un compilatore C++ potrebbe benissimo rendersi conto che il tuo ciclo è equivalente ad un assegnamento e sostituirlo senza pensarci due volte (a meno che tu abbia dichiarato una opzione apposita per impedirlo).

    I compilatori ti offrono di solito una serie di opzioni per regolare il livello di ottimizzazione, agendo sulle quali puoi ottenere prestazioni differenti.

    Il codice che hai scritto è C# ma immagino che il tuoi discorso sia generico. Comunque in C# esiste una opzione 'optimize code'.
  • Re: Velocità di lettura di un codice

    barba59 ha scritto:


    un compilatore C++ potrebbe benissimo rendersi conto che il tuo ciclo è equivalente ad un assegnamento e sostituirlo senza pensarci due volte.
    Visto che avevo ragione a voler sostituire il ciclo!

    Non credevo che si arrivasse a tanto, quali altri tipi di ottimizzazioni fa un compilatore?
  • Re: Velocità di lettura di un codice

    Leggi quest' articolo che è un pò vecchio ma è chiaro:

    http://www.eptacom.net/pubblicazioni/pub_it/optimize.html

    considera che da quell' articolo è passata molta acqua sotto i ponti, per cui immagina cosa ti possono combinare i compilatori moderni.
  • Re: Velocità di lettura di un codice

    Una trattazione completa dell'argomento di ottimizzazione del codice per aumentare la velocità di esecuzione e' talmente ampio che di articoli e libri ne sono stati scritti una pletora..

    la velocità di esecuzione di un codice dipende da diversi fattori:
    1) l'hardware sul quale gira
    2) il linguaggio nel quale e' stato scritto
    3) il problema che deve risolvere (l'algoritmo che implementa)
    4) il modo con cui il programma risolve il problema. (si suppone per semplicità che il programmatore sappia quello che sta facendo e non utilizza un algoritmo piu complesso del necessario)

    vediamo il punto 2)
    il linguaggio piu performante e' il inguaggio Assembly, un linguaggio che traduce i codici mnemonici del linguaggio direttamente in istruzioni in linguaggio macchina.
    ma proprio per le sue peculiarità e' un linguaggio che non viene usato per sviluppare applicazioni complesse.

    il linguaggio C e la sua versione ad oggetti il C++ sono meno performanti dell'assembly ma tra i linguaggi di programmazione sono i linguaggi ad alto livello piu performanti.

    ci sono poi i linguaggi interpretati come java, l'esecuzione del codice sviluppato con questi linguaggi viene eseguito da una "macchina virtuale" che e' un ulteriore strato di software e quindi risulta essere piu lento.

    per il punto 3) la trattazione e' ancora piu lunga ma possiamo fare un breve riassunto...
    ogni problema che puo' essere risolto tramite un pc, quindi un problema computazionale puo' essere implementato (cioe' viene scritto un programma che lo risolve) in molti modi e in differenti complessità.
    ogni problema ha una complessità minima intrinseca, al di sotto della quale non si puo' scendere, ma si puo' salire a piacere rendendo il programma scritto inefficiente.

    ad esempio, il problema piu classico che chiarisce cosa e' la complessità e' il problema dell'ordinamento.

    abbiamo una lista di N numeri e vogliamo ordinarli dal piu piccolo al piu grande...

    l'algoritmo piu semplice e':

    1: trovo il numero piu piccolo della lista A
    2: lo inserisco nella lista B
    3: lo elimino dalla lista A
    4: la lista A e' vuota? no: riparto dal punto 1, si: proseguo..
    5: restituisco la lista B ordinata

    questo semplice problema viene risolto in N x N elaborazioni... perche' per ogni iterazione devo scorrere tutta la lista A per trovare il piu piccolo.

    quindi per una lista di 10 elementi, faccio 100 operazioni
    per una lista di 100... 10.000
    per una lista di 1000... 1.000.000 un milione... davvero?

    come abbiamo visto all'aumentare di N le cose vanno sempre peggio...
    ma esistono algoritmi che permettono di risolvere il problema con complessità inferiore.
    ad esempio il merge sort o il quick sort, che hanno un tempo di elaborazione media di NxLog(N)

    per 1000 numeri il quick sort impiega NxLog(N) iterazioni.. cioe' 1000x3 = 3000

    3000 contro 1.000.000 ???

    esatto, quindi per velocizzare l'elaborazione la prima cosa da fare e' di trovare l'algoritmo ottimizzato che risolve quel problema con meno iterazioni possibili.
  • Re: Velocità di lettura di un codice

    Hev87 ha scritto:


    Vi ringrazio per le vostre risposte.

    Come avrete notato, sono piuttosto ignorante in campo di programmazione e capiterà spesso, almeno per i primi tempi, sentirmi adottare termini inadeguati e difficilmente comprensibili.
    Ho provato ad informarmi sul web prendendo come spunto le indicazioni contenute nelle vostre risposte, tuttavia l'unico risultato che ottengo è un allucinante mal di testa dopo aver tentato invano di comprendere il linguaggio tecnico con cui si esprimono gli esperti
    Leggendo le vostre risposte ho capito che ciò che malamente definivo "velocità di lettura" è in realtà la velocità di esecuzione.
    Scrivendo un codice del genere ad esempio:

    static void Main()
    { DateTime Beg = DateTime.Now;
    for (z = 0; z < 1000000000; z++)
    {
    n++;
    }
    DateTime End = DateTime.Now;

    Console.WriteLine(" tempo impiegato = {1} ", End-Beg);
    Console.ReadLine();
    }

    L'Output sarà " tempo impiegato = 00:00:06.199488 ";

    L'obiettivo è ridurre il più possibile quel "06"...
    migliorabile, dicevi che è possibile incrementare la velocità d'esecuzione tramite strutture dati di supporto. Cosa sarebbero di preciso queste strutture? Come si realizzano?

    Ringrazio per la disponibilità e la pazienza
    A mio giudizio per valutare devi prima partire da una considerazione di base; la CPU di un computer può eseguire un algoritmo descritto sia come linguaggio "interpretato" sia come linguaggio "compilato".

    La "lettura di codice" della quale tu parli è proprio la fase di interpretazione del codice tipica dei linguaggi interpretati. Esiste un sorgente del programma in formato testuale, esiste un programma apposito che si chiama interprete, l'interprete esegue una continua scansione del sorgente e quindi "mette in opera" le varie istruzioni da lui incontrate. Se tu scrivi 1 miliardo di cicli for, l'interprete legge e interpreta 1 miliardo di volte quel codice.
    Attenzione però che qui parliamo di tecnologie di almeno 30 anni orsono, l'esempio che mi viene in mente adesso è quello del GWBasic del DOS. Linguaggi interpretati più moderni mettono in pratica delle tecniche di ottimizzazione, tokenizzazione, decodifica preventiva e così via.

    La "compilazione" del codice è questione radicalmente diversa; nei computer la CPU esegue solo e unicamente un suo particolare linguaggio, l'assembler, fatto di istruzioni che nulla hanno in comune con gli usuali linguaggi di programmazione. La CPU carica dalla memoria tale codice assembler e lo esegue. Esistono degli algoritmi molto complessi detti "compilatori", che permettono di convertire un linguaggio di programmazione usuale nel corrispondente linguaggio assembler. I compilatori mettono in pratica una completa destrutturazione del codice, ovvero fanno "sparire" i cicli for, i cicli while, gli assegnamenti e così via. Il tuo ciclo for da 1 a 1 miliardo viene sostituito con un contatore che viene via via incrementato, poi confrontato con il valore limite fisso di 1 miliardo, quindi si passa attraverso una particolare istruzione di "salto condizionato", che è una sorta di GOTO del BASIC, e il ciclo ricomincia, oppure salta alla fine se si è arrivati a 1 miliardo.

    A voler essere precisi, anche l'assembler sarebbe un linguaggio "interpretato", nel senso che la CPU stessa costituisce un algoritmo di interpretazione ed esecuzione "scolpito" nel silicio, quindi velocissimo. La base di tale opera è costituita da degli esecutori, che non sono altro che automi a stati finiti realizzati nel silicio mediante gate logici, che non operano attraverso un linguaggio di programmazione bensì attraverso molteplici (e contorte) transizioni di stato.

    Per quanto ti riguarda, per il tuo voler fare il ciclo il più veloce possibile, lo devi fare direttamente in linguaggio assembler. Oppure usi il linguaggio C++ , che è quello che "codifica" nel modo più sgamato possibile, a volte il compilatore C++ crea delle vere e proprie opere d'arte di ottimizzazione, e per fare meglio del compilatore C++ ci deve mettere mano un programmatore assembler decisamente skillato.

    Se vuoi andare MOLTO veloce, allora non ti rimane che programmare a livello di gate logici; devi fare affidamento a potenti logiche programmabili (a questo punto neanche una CPU ti basta per i tuoi scopi), devi descrivere dei circuiti di calcolo a livello di gate o a livello di comportamento (behavioral), devi sintatizzarli dentro ad una FPGA o ASIC, quindi li puoi lanciare a velocità mai viste prima.

    Una simile tecnologia ad esempio torna utile nel momento in cui si vogliano implementare particolari algoritmi a velocità estrema, come algoritmi di cifratura, generazione di CRC, generazione di numeri pseudocasuali, cracking di password brute force e così via. La funzione la si realizza su silicio, va velocissima, e costa un botto!!

    Spero di essere stato sufficientemente esaustivo.
Devi accedere o registrarti per scrivere nel forum
11 risposte