I am interested in learning how I can improve the speed of the code in this pygame file. I iterate over 6400 * 1800 * 3 or 34,560,000 elements of various numpy arrays here to apply noise values to them. The noise library I'm using can be found on GitHub here.
I am calling static variables from a class called ST
here. ST.MAP_WIDTH
= 6400 and ST.MAP_HEIGHT
= 1800. All other ST
attributes called here are assigned in the code. They are the noise-maps I'm making.
from __future__ import division
from singleton import ST
import numpy as np
import noise
import timeit
import random
import math
def __noise(noise_x, noise_y, octaves=1, persistence=0.5, lacunarity=2.0):
"""
Generates and returns a noise value.
:param noise_x: The noise value of x
:param noise_y: The noise value of y
:return: numpy.float32
"""
value = noise.pnoise2(noise_x, noise_y,
octaves, persistence, lacunarity,
random.randint(1, 9999))
return np.float32(value)
def __elevation_mapper(noise_x, noise_y):
"""
Finds and returns the elevation noise for the given noise_x and
noise_y parameters.
:param noise_x: noise_x = x / ST.MAP_WIDTH - randomizer
:param noise_y: noise_y = y / ST.MAP_HEIGHT - randomizer
:return: float
"""
return __noise(noise_x, noise_y, 8, 0.9)
def __climate_mapper(y, noise_x, noise_y):
"""
Finds and returns the climate noise for the given noise_x and
noise_y parameters.
:param noise_x: noise_x = x / ST.MAP_WIDTH - randomizer
:param noise_y: noise_y = y / ST.MAP_HEIGHT - randomizer
:return: float
"""
# find distance from bottom of map and normalize to range [0, 1]
distance = math.sqrt((y - (ST.MAP_HEIGHT >> 1))**2) / ST.MAP_HEIGHT
value = __noise(noise_x, noise_y, 8, 0.7)
return (1 + value - distance) / 2
def __rainfall_mapper(noise_x, noise_y):
"""
Finds and returns the rainfall noise for the given noise_x and
noise_y parameters.
:param noise_x: noise_x = x / ST.MAP_WIDTH - randomizer
:param noise_y: noise_y = y / ST.MAP_HEIGHT - randomizer
:return: float
"""
return __noise(noise_x, noise_y, 4, 0.65, 2.5)
def create_map_arr():
"""
This function creates the elevation, climate, and rainfall noise maps,
normalizes them to the range [0, 1], and then assigns them to their
appropriate attributes in the singleton ST.
"""
start = timeit.default_timer()
elevation_arr = np.zeros([ST.MAP_HEIGHT, ST.MAP_WIDTH], np.float32)
climate_arr = np.zeros([ST.MAP_HEIGHT, ST.MAP_WIDTH], np.float32)
rainfall_arr = np.zeros([ST.MAP_HEIGHT, ST.MAP_WIDTH], np.float32)
randomizer = random.uniform(0.0001, 0.9999)
# assign noise map values
for y in range(ST.MAP_HEIGHT):
for x in range(ST.MAP_WIDTH):
noise_x = x / ST.MAP_WIDTH - randomizer
noise_y = y / ST.MAP_HEIGHT - randomizer
elevation_arr[y][x] = __elevation_mapper(noise_x, noise_y)
climate_arr[y][x] = __climate_mapper(y, noise_x, noise_y)
rainfall_arr[y][x] = __rainfall_mapper(noise_x, noise_y)
# normalize to range [0, 1] and assign to relevant ST attributes
ST.ELEVATIONS = (elevation_arr - elevation_arr.min()) / \
(elevation_arr.max() - elevation_arr.min())
ST.CLIMATES = (climate_arr - climate_arr.min()) / \
(climate_arr.max() - climate_arr.min())
ST.RAINFALLS = (rainfall_arr - rainfall_arr.min()) / \
(rainfall_arr.max() - rainfall_arr.min())
stop = timeit.default_timer()
print("GENERATION TIME: " + str(stop - start))
numpy.meshgrid
and its examples. I think they'll do what you need. \$\endgroup\$