Gå til innhold

Anbefalte innlegg

Hei, jeg har installert python runtimes og jeg lurer på hvilke metoder jeg kan bruke for å mest effektivt generere random integere på raskest mulig måte, hvilken metode er raskest? Jeg ønsker å se om jeg kan slå min egen assembler generator. Hvor mange tall per sekund kan jeg generere random ints i python?

 

Kan noen hjelpe meg å sette opp et python script for å teste hastigheten? Det hadde vært gøy å se om pypy er raskere på random ints (SNIPPSAT) snakket om pypy i går i en annen tråd, jeg vet ikke om pypy har noen form for optimalisering der. Jeg har ingen anelse hvor jeg ligger an hen i forhold til python (eller andre språk for den slags skyld)

Endret av LonelyMan
Lenke til kommentar
Videoannonse
Annonse

Python er ikke min sterkeste side, men noe i retning av dette (Python 2.7):

 

import random
import datetime
start = datetime.datetime.now()
for i in range(0, 1000000):
 random.randint(0, 1000000)
end = datetime.datetime.now()
delta = end - start
print("Microseconds: %i" % delta.microseconds)

 

Genererer 1 million tall mellom 0-1000000. Den skriver ikke ut til skjerm etterhvert som den lager tallene. Vær obs på at det kan nok være raskere måter å gjøre det på.

Endret av grapz
Lenke til kommentar

Endret koden litt for å bruke cProfile i stedet for time.

 

Så, det tar 2.366 sekunder å kjøre 1000000 randoms.

 

Så hos meg tar det 2.366 mikrosekund per random.

 

Oppdatert kode:

import random
import cProfile
import pstats


def genrand():
 for i in range(0, 1000000):
   random.randint(0, 1000000)

def measure():
 cProfile.run('genrand()', 'randstat')
 p = pstats.Stats('randstat')
 p.sort_stats('name')
 p.print_stats()


measure()

Endret av grapz
Lenke til kommentar

Her er min output (Python 3.2) på en i5-3470 @ 3.2GHz:

 

p.strip_dirs().print_stats()

Fri Dec 21 12:33:50 2012    randstat


	 5048652 function calls in 2.359 seconds

  Random listing order was used


  ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    1    0.000    0.000    2.359    2.359 {built-in method exec}
 1000000    0.393    0.000    2.093    0.000 random.py:211(randint)
 1048648    0.252    0.000    0.252    0.000 {method 'getrandbits' of '_random.Random' objects}
 1000000    0.763    0.000    1.699    0.000 random.py:166(randrange)
    1    0.266    0.266    2.359    2.359 <pyshell#6>:1(genrand)
    1    0.000    0.000    2.359    2.359 <string>:1(<module>)
 1000000    0.628    0.000    0.936    0.000 random.py:217(_randbelow)
    1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
 1000000    0.056    0.000    0.056    0.000 {method 'bit_length' of 'int' objects}

Lenke til kommentar

Hvor raskt genererer de tall i den linken du linker til siDDis, er den forskjellig fra den vi bruker her? Random rutinen behøver ikke være kryptografisk sikker, den skal bare være noenlunde random, ha kommet gjennom diehard testen.

Endret av LonelyMan
Lenke til kommentar

Tja, den genererer ikke ca 5 millioner nummer, men randint metoden er ikke i bunnen av random stacken, så den må kalle seg nedover. Så hver randint kall resulterer i 4 andre metodekall, så da ender jeg opp på ca 5 millioner.

 

siDDis, ja stemmer bra det.

Lenke til kommentar

Men siden python er et scriptespråk så kan det høres ut som inlining ikke er mulig eller tar jeg feil her, kan man inline random funksjonen du bruker?

 

Tenker du noe i retning av dette:

 

def measure():
   cProfile.run('[random.randint(0, 1000000) for x in range(0, 1000000)]', 'randstat')
   p = pstats.Stats('randstat')
   p.sort_stats('name')
   p.print_stats()

Endret av grapz
Lenke til kommentar

For effektivt bruk av tall i Python, så vill jeg brukt biblioteket "numPy". Der er veldig mange ting ferdig implementert med effektive algoritmer.

 

Da kan du skrive kode lignende dette:

import numpy
randInts = nympy.random.randint(1000, size=10000)

 

Dette vil generere 10000 random integere, mellom 0 og 1000. Med bruk av numPy vil du få en implementasjon som er over 100 ganger raskere. (målinger på min maskin ga meg 150 ganger raskere).

Lenke til kommentar

Stjeler dette fra stackoverflow:

import timeit

t1 = timeit.Timer('[random.randint(0,1000) for r in xrange(10000)]','import random') # v1
### change v2 so that it picks numbers in (0,10000) and thus runs...
t2 = timeit.Timer('random.sample(range(10000), 10000)','import random') # v2
t3 = timeit.Timer('nprnd.randint(1000, size=10000)','import numpy.random as nprnd') # v3

print t1.timeit(1000)/1000
print t2.timeit(1000)/1000
print t3.timeit(1000)/1000

 

Resultater fra han som svarte (kjøretid), nederste er med numpy

0.0233682730198

0.00781716918945

0.000147947072983

 

Edit: Glemte å importere timeit.

Endret av etse
Lenke til kommentar

Er det millisekund?

nei, sekunder.Hver av de genererer 10.000 tall. Gjør dette 1000 ganger og tar gjennomsnitt. Så du ser at python sin innebygde er meget treg.

 

Edit: altså er det tid i sekunder det tar å generere 10.000 tilfeldige tall. Ikke for et tall.

Endret av etse
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...