• [^] # Re: Ruby

    Posté par . En réponse au journal A mort les boucles. Évalué à 3.

    Je viens de le dire: la première version va te bourrer la mémoire et mettre à genou ton CPU, parce qu'elle va créer un tableau de 20000000 entiers pour ensuite le parcourir
    La deuxième version va simplement créer un itérateur, qui ne mémorise que l'état courant et qui ne sait rien faire d'autre qu'aller à l'état suivant. C'est plus économique en mémoire et en temps CPU.
    En gros:
    >>> x = range(5)
    >>> print x
    [1, 2, 3, 4]
    >>> x = xrange(5)
    >>> print x
    xrange(5)
    >>> print x.next()
    0
    >>> print x.next()
    1
    >>> print x.next()
    2
    ...
    Remplace 5 par 2000000. Tu vois tout de suite que ton range va sacrément bourrer à la fois ta mémoire et ton CPU, tandis que le xrange ne coutera rien en plus.

    C'est quelque chose de bien plus général qu'un simple intervalle. S'il est évident qu'un programmeur d'écrira JAMAIS range(2000000), on peut par contre voir par exemple:
    data = [line.split(',') for line in open('data.csv').read().splitlines()]
    qui fonctionnera pour des tests basiques, mais qui est plutôt inefficace:
    - ton fichier est entièrement gardé en mémoire (read())
    - il est gardé une deuxième fois en mémoire (chaque ligne comme un élément d'un tableau: splitlines())
    - enfin, il est gardé une troisième fois en mémoire (chque ligne séparée en champ)
    Tu auras aussi du utiliser 3 fois le contenu de ton fichier pour simplement afficher tous les premiers champs par exemple:
    - d'abord en lisant entièrement le fichier (le read())
    - ensuite en itérant sur les données pour les traiter ligne par ligne (le splitline)
    - ensuite en itérant sur data

    Avec un itérateur:
    data = (line.split(',') for line in open('data.cvs').xreadlines())
    ton fichier n'est lu qu'une fois en mémoire, les données ne dont itérées que si nécessaire: cout mémoire virtuellement nul et efficacité optimale. Si ton fichier fait 300 Mo et que tu ne veux que les trois premiers enregistrements, la première version nacéssitera de parse et de garder en mémoire les 300 Mo. La deuxième ne prendra pas plus de mémoire que si ton fichier faisait 5 Go ou 5 octets, et ne prendra que le temps nécessaire à lire les trois premiers enregistrements

    La différence, c'est que le premier est un tableau. Le deuxième est un itérateur (plus précisement, un générateur). C'est la même différence qu'entre un range et un tableau. Vois tu l'intérêt de les différencier, maintenant ? :p