Skip to content

Latest commit

 

History

History
68 lines (56 loc) · 2.89 KB

readme.rst

File metadata and controls

68 lines (56 loc) · 2.89 KB

xrand: Extremely fast Cpython PRNG lib

Implemented entirely in C with micro-optimized code, including a significant rewrite of Python's abstract object API, xrand gives Python the ability to compete with compiled languages for developing software which makes heavy use of random number generation.

Includes all features from the standard library module random.py and more.

Some comparisons

Here's a quick script comparing the difference in function calls per second xrand is capable of versus the equivalent random.py function. (ran on Ivy Bridge Core i7 on Windows 32-bit Python 3.6.0)

import random
from functools import partial
from itertools import product, repeat, starmap

import xrand
from tabulate import tabulate
from xrand import *

def compare(f, xrv, pyv, *args, xargs=None, rep='', **kws):
    xargs = kws.pop('xargs', args)
    x = perf(getattr(xrand, xrv), xargs)
    y = perf(getattr(random, pyv), args)
    z = x/y-1.0
    data.append([f'{f}({rep})', x, y, z])

cards = [f'{a}{b}' for a,b in product('HSDC',(*'23456789','10',*'JKQA'))]
loaded_dice = choices({1:1, 2:1, 3:1, 4:1, 5:1, 6:5})
py_pop, py_weights = loaded_dice.population
py_dice = partial(random.choices,py_pop, cum_weights=py_weights)
data = [('f', 'xrand', 'random', 'dif')]

a = perf(iter_beta(None, 3.0, 3.0).take)
b = perf(random.betavariate, (3.0, 3.0))
data.append(['betavariate(3.0, 3.0)', a, b, a/b])
compare('choice', 'select', 'choice', cards, rep='cards')
a = perf(loaded_dice.next_n, (10,))
b = perf(py_dice, (), {'k':10})
data.append(['choices(cards, k=10)', a, b, a/b])
compare('shuffle', 'shuffle', 'shuffle', cards, rep='cards')
compare('sample', 'sample', 'sample', cards, 20, rep='cards, 20')
compare('randint', 'rand_int', 'randint', 0, 385, xargs=(385,), rep='385')
compare('random', 'rand_float', 'random')
compare('randrange', 'rand_index', 'randrange', 76000, rep='76000')
for i, (a, b, c, d) in enumerate(data[1:], 1):
    data[i] = [a, f'{round(b):_}', f'{round(c):_}', f'{d:+,.0%}']

>>> print(tabulate(data))
---------------------  ----------  ----------  -------
f                      xrand       random      dif
betavariate(3.0, 3.0)  4_181_041   163_915     +2,551%
choice(cards)          18_632_245  759_560     +2,353%
choices(cards, k=10)   2_618_083   126_883     +2,063%
shuffle(cards)         1_480_818   16_220      +9,029%
sample(cards, 20)      1_329_424   30_537      +4,253%
randint(385)           11_644_439  455_809     +2,455%
random()               33_648_747  27_141_605  +24%
randrange(76000)       14_391_397  588_787     +2,344%
---------------------  ----------  ----------  -------