mardi 30 mai 2017

Python map generation, random.seed performance

I'm using random midpoint displacement algorithm to generate height-maps. In order to keep things depend exclusively on the coordinates and a seed I use the following function and method:

import random    


class HeightMap(object):
    def __init__(self, ..., seed=None, bit_length=64):
         ...
         self.bit_length = bit_length
         self.seed = seed if seed is not None else random.randint(0, 1 << self.bit_length)
         self.coord_min, self.coord_max = (-1 << (self.bit_length >> 1) - 1,
                                           (1 << (self.bit_length >> 1) - 1) - 1)

    ...

    def get_random_at(self, x, y, a, b):
        random.seed(get_seed_at(self.seed, x, y, self.bit_length))
        return random.uniform(a, b)

def get_seed_at(seed, x, y, bit_length):
    return (seed + ((x << (bit_length >> 1)) + y + (1 << (bit_length >> 1) - 1))) % (1 << bit_length)

This might seems a bit spaghetti. What the get_seed_at function does, it the copies the x coordinates and y coordinates into an integer (with size of bit_length) to it's upper and lower bits, adds seed to this and makes sure it stays bit_length wide by taking it's modulo.

Then get_random_at method uses the integer provided to seed the random module's Random singleton. This is thread safe, even though it does not have a designated instance, but more importantly it generates the same map from the same given seed every time no matter which order I request the chunks to be created.

My issue is, after some optimization I manage to narrow the bottle neck to random.seed. At this point it almost takes up half of the run time.

Is there any suggestions how to improve on this? Or a better approach to solve this all together?

Many thanks.




Aucun commentaire:

Enregistrer un commentaire