Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentes Révision précédente | Prochaine révision Les deux révisions suivantes | ||
dichotomie [2009/04/20 07:25] tyrtamos |
dichotomie [2009/04/20 08:36] tyrtamos |
||
---|---|---|---|
Ligne 245: | Ligne 245: | ||
<code python> | <code python> | ||
import random | import random | ||
+ | import time | ||
def creafic(fichier, | def creafic(fichier, | ||
Ligne 261: | Ligne 262: | ||
f.write(v + esp[: | f.write(v + esp[: | ||
f.close() | f.close() | ||
+ | |||
+ | fichier = " | ||
+ | lg = 1000000 | ||
+ | lge = 5 | ||
+ | i1 = 1000 | ||
+ | i2 = 9999 | ||
+ | creafic(fichier, | ||
+ | print u" | ||
</ | </ | ||
Ligne 281: | Ligne 290: | ||
<code python> | <code python> | ||
+ | f = open(fichier, | ||
+ | t1 = 0 | ||
+ | t2 = 0 | ||
+ | c = 0 | ||
+ | while True: | ||
+ | try: | ||
+ | c += 1 | ||
+ | x = random.randint(i1-1, | ||
+ | |||
+ | t = time.clock() | ||
+ | r,i = dichot(x, I, key=litdata) | ||
+ | t1 += time.clock()-t | ||
+ | |||
+ | t = time.clock() | ||
+ | r,i = seq(x, I, key=litdata) | ||
+ | t2 += time.clock()-t | ||
+ | |||
+ | print [r, i], litdata(i), t2/t1, t1/c | ||
+ | except: | ||
+ | break | ||
+ | f.close() | ||
+ | </ | ||
+ | |||
+ | Le résultat est époustouflant: | ||
+ | |||
+ | Ça vous suffit comme performance? | ||
+ | |||
+ | NB: je ne connais pas l' | ||
+ | |||
+ | ===== Recherche indexée dans un fichier sur disque ===== | ||
+ | |||
+ | On se propose ici de rechercher des valeurs par dichotomie avec un fichier disque **non trié**, et sans charger ce fichier en mémoire. On va donc créer un fichier d' | ||
+ | |||
+ | On va d' | ||
+ | |||
+ | <code python> | ||
+ | import random | ||
import time | import time | ||
+ | |||
+ | def creafic(fichier, | ||
+ | # fabrication de la liste à enregistrer | ||
+ | L = [random.randint(i1, | ||
+ | |||
+ | # creation du fichier sur disque | ||
+ | f = open(fichier, | ||
+ | esp = ' '*lge | ||
+ | for i in range(0, len(L)): | ||
+ | f.seek(i*lge) | ||
+ | v = " | ||
+ | f.write(v + esp[: | ||
+ | f.close() | ||
fichier = " | fichier = " | ||
lg = 1000000 | lg = 1000000 | ||
lge = 5 | lge = 5 | ||
- | i1 = int(' | + | I1 = 1000 |
- | i2 = int(' | + | I2 = 9999 |
- | print u" | + | |
+ | t = time.clock() | ||
+ | creafic(fichier, lg, lge, I1, I2) | ||
+ | t = time.clock()-t | ||
+ | print u" | ||
+ | </ | ||
+ | |||
+ | La création de ce fichier d'1 million d' | ||
+ | |||
+ | Maintenant, on va créer un fichier d' | ||
+ | |||
+ | <code python> | ||
+ | def litdata(i): | ||
+ | global f, lge | ||
+ | f.seek(i*lge) | ||
+ | return int(f.read(lge).strip()) | ||
- | creafic(fichier, | ||
I = [i for i in xrange(0, | I = [i for i in xrange(0, | ||
- | print u" | + | f = open(fichier, |
+ | t = time.clock() | ||
+ | I.sort(key=litdata) | ||
+ | t = time.clock()-t | ||
+ | f.close() | ||
+ | print u" | ||
+ | </ | ||
+ | La création de ce fichier d' | ||
+ | |||
+ | Si vous voulez le vérifier, vous pouvez afficher les données du disque dans cet ordre comme suit. Mais ne le faites pas pour le fichier de 1000000 de valeurs: cela demandera trop de temps pour l' | ||
+ | |||
+ | <code python> | ||
+ | f = open(fichier, | ||
+ | for i in I: | ||
+ | print litdata(i) | ||
+ | |||
+ | f.close() | ||
+ | </ | ||
+ | |||
+ | Voilà. Maintenant, tout est en place pour la recherche par dichotomie: | ||
+ | |||
+ | <code python> | ||
f = open(fichier, | f = open(fichier, | ||
t1 = 0 | t1 = 0 | ||
Ligne 301: | Ligne 395: | ||
try: | try: | ||
c += 1 | c += 1 | ||
- | x = random.randint(i1-1, i2+1) | + | x = random.randint(I1-1, I2+1) |
t = time.clock() | t = time.clock() | ||
- | | + | |
t1 += time.clock()-t | t1 += time.clock()-t | ||
t = time.clock() | t = time.clock() | ||
- | | + | |
t2 += time.clock()-t | t2 += time.clock()-t | ||
- | print [r, i], litdata(i), t2/t1, t1/c | + | print x, [r1, i1], [r2, i2], litdata(I[i1]), litdata(I[i2]), t2/t1, t1/c |
except: | except: | ||
break | break | ||
Ligne 317: | Ligne 411: | ||
</ | </ | ||
- | Le résultat est époustouflant: | + | Le code ci-dessus (qu'on arrête avec Ctrl-C) affiche les résultats comme suit: |
- | * On trouve une valeur au hasard parmi un million de valeurs sur disque en 1.7/10000 secondes, et c'est 17000 fois plus rapidement qu' | + | < |
- | + | 8317 [0, 813361] [0, 813361] 8317 8317 17537.9140573 0.000173003674181 | |
- | Ça vous suffit comme performance? | + | 8476 [0, 830810] [0, 830810] 8476 8476 17587.4199338 0.000173009098294 |
- | + | 4398 [0, 377556] [0, 377556] 4398 4398 17571.9584712 0.000172991006654 | |
- | NB1: je ne connais pas l' | + | 5537 [0, 504304] [0, 504304] 5537 5537 17575.2446774 0.000172973807046 |
+ | </ | ||
- | NB2: j'ai pris ici un fichier | + | Ce qui montre une performance quasi identique au test précédent: le passage par une liste d'index n'a donc pas ralenti sensiblement le temps de recherche: la recherche dichotomique sur disque, |
\\ | \\ |