forked from mynameisfiber/high_performance_python
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit ac9c6d2
Showing
347 changed files
with
616,559 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
*.pyc |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
"""Julia set generator without optional PIL-based image drawing""" | ||
import time | ||
from PIL import Image | ||
import array | ||
|
||
# area of complex space to investigate | ||
x1, x2, y1, y2 = -1.8, 1.8, -1.8, 1.8 | ||
c_real, c_imag = -0.62772, -.42193 | ||
|
||
|
||
def show_greyscale(output_raw, width, height, max_iterations): | ||
"""Convert list to array, show using PIL""" | ||
# convert our output to PIL-compatible input | ||
# scale to [0...255] | ||
max_iterations = float(max(output_raw)) | ||
print max_iterations | ||
scale_factor = float(max_iterations) | ||
scaled = [int(o / scale_factor * 255) for o in output_raw] | ||
output = array.array('B', scaled) # array of unsigned ints | ||
# display with PIL | ||
im = Image.new("L", (width, width)) | ||
# EXPLAIN RAW L 0 -1 | ||
im.frombytes(output.tostring(), "raw", "L", 0, -1) | ||
im.show() | ||
|
||
|
||
def show_false_greyscale(output_raw, width, height, max_iterations): | ||
"""Convert list to array, show using PIL""" | ||
# convert our output to PIL-compatible input | ||
assert width * height == len(output_raw) # sanity check our 1D array and desired 2D form | ||
# rescale output_raw to be in the inclusive range [0..255] | ||
max_value = float(max(output_raw)) | ||
output_raw_limited = [int(float(o) / max_value * 255) for o in output_raw] | ||
# create a slightly fancy colour map that shows colour changes with | ||
# increased contrast (thanks to John Montgomery) | ||
output_rgb = ((o + (256 * o) + (256 ** 2) * o) * 16 for o in output_raw_limited) # fancier | ||
output_rgb = array.array('I', output_rgb) # array of unsigned ints (size is platform specific) | ||
# display with PIL/pillow | ||
im = Image.new("RGB", (width, height)) | ||
# EXPLAIN RGBX L 0 -1 | ||
im.frombytes(output_rgb.tostring(), "raw", "RGBX", 0, -1) | ||
im.show() | ||
|
||
|
||
def calculate_z_serial_purepython(maxiter, zs, cs): | ||
"""Calculate output list using Julia update rule""" | ||
output = [0] * len(zs) | ||
for i in range(len(zs)): | ||
n = 0 | ||
z = zs[i] | ||
c = cs[i] | ||
while abs(z) < 2 and n < maxiter: | ||
z = z * z + c | ||
n += 1 | ||
output[i] = n | ||
return output | ||
|
||
|
||
def calc_pure_python(draw_output, desired_width, max_iterations): | ||
"""Create a list of complex co-ordinates (zs) and complex parameters (cs), build Julia set and display""" | ||
x_step = (float(x2 - x1) / float(desired_width)) | ||
y_step = (float(y1 - y2) / float(desired_width)) | ||
x = [] | ||
y = [] | ||
ycoord = y2 | ||
while ycoord > y1: | ||
y.append(ycoord) | ||
ycoord += y_step | ||
xcoord = x1 | ||
while xcoord < x2: | ||
x.append(xcoord) | ||
xcoord += x_step | ||
# set width and height to the generated pixel counts, rather than the | ||
# pre-rounding desired width and height | ||
width = len(x) | ||
height = len(y) | ||
# build a list of co-ordinates and the initial condition for each cell. | ||
# Note that our initial condition is a constant and could easily be removed, | ||
# we use it to simulate a real-world scenario with several inputs to our function | ||
zs = [] | ||
cs = [] | ||
for ycoord in y: | ||
for xcoord in x: | ||
zs.append(complex(xcoord, ycoord)) | ||
cs.append(complex(c_real, c_imag)) | ||
|
||
print "Length of x:", len(x) | ||
print "Total elements:", len(zs) | ||
start_time = time.time() | ||
output = calculate_z_serial_purepython(max_iterations, zs, cs) | ||
end_time = time.time() | ||
secs = end_time - start_time | ||
print calculate_z_serial_purepython.func_name + " took", secs, "seconds" | ||
|
||
assert sum(output) == 33219980 # this sum is expected for 1000^2 grid with 300 iterations | ||
|
||
if draw_output: | ||
#show_false_greyscale(output, width, height, max_iterations) | ||
show_greyscale(output, width, height, max_iterations) | ||
|
||
|
||
if __name__ == "__main__": | ||
# Calculate the Julia set using a pure Python solution with | ||
# reasonable defaults for a laptop | ||
# set draw_output to True to use PIL to draw an image | ||
calc_pure_python(draw_output=True, desired_width=1000, max_iterations=300) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
"""Julia set generator without optional PIL-based image drawing""" | ||
import time | ||
|
||
# area of complex space to investigate | ||
x1, x2, y1, y2 = -1.8, 1.8, -1.8, 1.8 | ||
c_real, c_imag = -0.62772, -.42193 | ||
|
||
|
||
def calculate_z_serial_purepython(maxiter, zs, cs): | ||
"""Calculate output list using Julia update rule""" | ||
output = [0] * len(zs) | ||
for i in range(len(zs)): | ||
n = 0 | ||
z = zs[i] | ||
c = cs[i] | ||
while abs(z) < 2 and n < maxiter: | ||
z = z * z + c | ||
n += 1 | ||
output[i] = n | ||
return output | ||
|
||
|
||
def calc_pure_python(draw_output, desired_width, max_iterations): | ||
"""Create a list of complex co-ordinates (zs) and complex parameters (cs), build Julia set and display""" | ||
x_step = (float(x2 - x1) / float(desired_width)) | ||
y_step = (float(y1 - y2) / float(desired_width)) | ||
x = [] | ||
y = [] | ||
ycoord = y2 | ||
while ycoord > y1: | ||
y.append(ycoord) | ||
ycoord += y_step | ||
xcoord = x1 | ||
while xcoord < x2: | ||
x.append(xcoord) | ||
xcoord += x_step | ||
# build a list of co-ordinates and the initial condition for each cell. | ||
# Note that our initial condition is a constant and could easily be removed, | ||
# we use it to simulate a real-world scenario with several inputs to our function | ||
zs = [] | ||
cs = [] | ||
for ycoord in y: | ||
for xcoord in x: | ||
zs.append(complex(xcoord, ycoord)) | ||
cs.append(complex(c_real, c_imag)) | ||
|
||
print "Length of x:", len(x) | ||
print "Total elements:", len(zs) | ||
start_time = time.time() | ||
output = calculate_z_serial_purepython(max_iterations, zs, cs) | ||
end_time = time.time() | ||
secs = end_time - start_time | ||
print calculate_z_serial_purepython.func_name + " took", secs, "seconds" | ||
|
||
assert sum(output) == 33219980 # this sum is expected for 1000^2 grid with 300 iterations | ||
|
||
|
||
if __name__ == "__main__": | ||
# Calculate the Julia set using a pure Python solution with | ||
# reasonable defaults for a laptop | ||
# set draw_output to True to use PIL to draw an image | ||
calc_pure_python(draw_output=False, desired_width=1000, max_iterations=300) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
"""Julia set generator with timing decorator""" | ||
import time | ||
from functools import wraps | ||
|
||
# area of complex space to investigate | ||
x1, x2, y1, y2 = -1.8, 1.8, -1.8, 1.8 | ||
c_real, c_imag = -0.62772, -.42193 | ||
|
||
|
||
def timefn(fn): | ||
@wraps(fn) | ||
def measure_time(*args, **kwargs): | ||
t1 = time.time() | ||
result = fn(*args, **kwargs) | ||
t2 = time.time() | ||
print ("@timefn:" + fn.func_name + " took " + str(t2 - t1) + " seconds") | ||
return result | ||
return measure_time | ||
|
||
|
||
@timefn | ||
def calculate_z_serial_purepython(maxiter, zs, cs): | ||
"""Calculate output list using Julia update rule""" | ||
output = [0] * len(zs) | ||
for i in range(len(zs)): | ||
n = 0 | ||
z = zs[i] | ||
c = cs[i] | ||
while abs(z) < 2 and n < maxiter: | ||
z = z * z + c | ||
n += 1 | ||
output[i] = n | ||
return output | ||
|
||
|
||
def calc_pure_python(draw_output, desired_width, max_iterations): | ||
"""Create a list of complex co-ordinates (zs) and complex parameters (cs), build Julia set and display""" | ||
x_step = (float(x2 - x1) / float(desired_width)) | ||
y_step = (float(y1 - y2) / float(desired_width)) | ||
x = [] | ||
y = [] | ||
ycoord = y2 | ||
while ycoord > y1: | ||
y.append(ycoord) | ||
ycoord += y_step | ||
xcoord = x1 | ||
while xcoord < x2: | ||
x.append(xcoord) | ||
xcoord += x_step | ||
# build a list of co-ordinates and the initial condition for each cell. | ||
# Note that our initial condition is a constant and could easily be removed, | ||
# we use it to simulate a real-world scenario with several inputs to our function | ||
zs = [] | ||
cs = [] | ||
for ycoord in y: | ||
for xcoord in x: | ||
zs.append(complex(xcoord, ycoord)) | ||
cs.append(complex(c_real, c_imag)) | ||
|
||
print "Length of x:", len(x) | ||
print "Total elements:", len(zs) | ||
start_time = time.time() | ||
output = calculate_z_serial_purepython(max_iterations, zs, cs) | ||
end_time = time.time() | ||
secs = end_time - start_time | ||
print calculate_z_serial_purepython.func_name + " took", secs, "seconds" | ||
|
||
assert sum(output) == 33219980 # this sum is expected for 1000^2 grid with 300 iterations | ||
|
||
|
||
# Calculate the Julia set using a pure Python solution with | ||
# reasonable defaults for a laptop | ||
# set draw_output to True to use PIL to draw an image | ||
calc_pure_python(draw_output=False, desired_width=1000, max_iterations=300) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
"""Julia set generator without optional PIL-based image drawing""" | ||
import time | ||
|
||
# area of complex space to investigate | ||
x1, x2, y1, y2 = -1.8, 1.8, -1.8, 1.8 | ||
c_real, c_imag = -0.62772, -.42193 | ||
|
||
|
||
def launch_memory_usage_server(port=8080): | ||
import cherrypy | ||
import dowser | ||
|
||
cherrypy.tree.mount(dowser.Root()) | ||
cherrypy.config.update({ | ||
'environment': 'embedded', | ||
'server.socket_port': port | ||
}) | ||
|
||
cherrypy.engine.start() | ||
|
||
|
||
def calculate_z_serial_purepython(maxiter, zs, cs): | ||
"""Calculate output list using Julia update rule""" | ||
output = [0] * len(zs) | ||
for i in range(len(zs)): | ||
n = 0 | ||
z = zs[i] | ||
c = cs[i] | ||
while n < maxiter and abs(z) < 2: | ||
z = z * z + c | ||
n += 1 | ||
output[i] = n | ||
return output | ||
|
||
|
||
def calc_pure_python(draw_output, desired_width, max_iterations): | ||
"""Create a list of complex co-ordinates (zs) and complex parameters (cs), build Julia set and display""" | ||
x_step = (float(x2 - x1) / float(desired_width)) | ||
y_step = (float(y1 - y2) / float(desired_width)) | ||
|
||
x = [] | ||
y = [] | ||
ycoord = y2 | ||
while ycoord > y1: | ||
y.append(ycoord) | ||
ycoord += y_step | ||
xcoord = x1 | ||
while xcoord < x2: | ||
x.append(xcoord) | ||
xcoord += x_step | ||
|
||
# set width and height to the generated pixel counts, rather than the | ||
# pre-rounding desired width and height | ||
# build a list of co-ordinates and the initial condition for each cell. | ||
# Note that our initial condition is a constant and could easily be removed, | ||
# we use it to simulate a real-world scenario with several inputs to our function | ||
zs = [] | ||
cs = [] | ||
for ycoord in y: | ||
for xcoord in x: | ||
zs.append(complex(xcoord, ycoord)) | ||
cs.append(complex(c_real, c_imag)) | ||
|
||
launch_memory_usage_server() | ||
|
||
print "Length of x:", len(x) | ||
print "Total elements:", len(zs) | ||
start_time = time.time() | ||
output = calculate_z_serial_purepython(max_iterations, zs, cs) | ||
end_time = time.time() | ||
secs = end_time - start_time | ||
print calculate_z_serial_purepython.func_name + " took", secs, "seconds" | ||
|
||
assert sum(output) == 33219980 # this sum is expected for 1000^2 grid with 300 iterations | ||
|
||
print "now waiting..." | ||
while True: | ||
time.sleep(1) | ||
|
||
|
||
if __name__ == "__main__": | ||
# Calculate the Julia set using a pure Python solution with | ||
# reasonable defaults for a laptop | ||
# set draw_output to True to use PIL to draw an image | ||
calc_pure_python(draw_output=False, desired_width=1000, max_iterations=300) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.