Skip to main content
Code Review

Return to Answer

replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link

There is no need to check for move==0 in the elif-part since you know the value can only be 0 or 1. Please use and and not the bitwise-and & when you concatenate booleans. See this this SO question for a elaborate explenation of the differences

There is no need to check for move==0 in the elif-part since you know the value can only be 0 or 1. Please use and and not the bitwise-and & when you concatenate booleans. See this SO question for a elaborate explenation of the differences

There is no need to check for move==0 in the elif-part since you know the value can only be 0 or 1. Please use and and not the bitwise-and & when you concatenate booleans. See this SO question for a elaborate explenation of the differences

Update to answer comments of OP.
Source Link
AlexV
  • 7.4k
  • 2
  • 24
  • 47

I threw a profiling program at your code (Spyder IDE built-in profiler ). The results showed, that most of the time is wasted on rand.randint(0, 1). Instead of calling rand.randint(0, 1) and checking for 0 and 1, use rand.random(). This will give you a random number in the interval \$ [0, 1)\$. Your condition will then become \$ < 0.5 \$. On my machine this reduced the time to run the code from about \10ドル\$-\12ドルs\$ to around \1ドル\$-\1ドル.5s\$, which is around an order of magnitude.

My theory on this is that Python uses an algorithm that builds on rand.random() (or at least the same source of random values) and maps those random values to integers based on the given limits in rand.randint(low, high). This mapping probably introduces an small overheard which is not to big to be a real problem if you do not call the function to often. But in your program, the function is called a lot (profiler says more than 4 million times), so the overhead sums up and becomes noteable.

There is no need to check for move==0 in the elif-part since you know the value can only be 0 or 1. Please use and and not the bitwise-and & when you concatenate booleans. See this SO question for a elaborate explenation of the differences

A note on numpy: I can not say for sure if there is a real performance difference using numpy instead of list for calculating the mean values etc.. I know from my experience, it has some seriously optimised algorithms that allow fast and numerically safe(r) computations on large arrays. Additionally, numpy allows convenient handling of list/arrays/matrices with more than one dimension. So in your case (without in-depth analysis) it basically comes down to personal preference and maybe convenience.

I threw a profiling program at your code. The results showed, that most of the time is wasted on rand.randint(0, 1). Instead of calling rand.randint(0, 1) and checking for 0 and 1, use rand.random(). This will give you a random number in the interval \$ [0, 1)\$. Your condition will then become \$ < 0.5 \$. On my machine this reduced the time to run the code from about \10ドル\$-\12ドルs\$ to around \1ドル\$-\1ドル.5s\$, which is around an order of magnitude.

There is no need to check for move==0 in the elif-part since you know the value can only be 0 or 1. Please use and and not the bitwise-and & when you concatenate booleans.

I threw a profiling program at your code (Spyder IDE built-in profiler ). The results showed, that most of the time is wasted on rand.randint(0, 1). Instead of calling rand.randint(0, 1) and checking for 0 and 1, use rand.random(). This will give you a random number in the interval \$ [0, 1)\$. Your condition will then become \$ < 0.5 \$. On my machine this reduced the time to run the code from about \10ドル\$-\12ドルs\$ to around \1ドル\$-\1ドル.5s\$, which is around an order of magnitude.

My theory on this is that Python uses an algorithm that builds on rand.random() (or at least the same source of random values) and maps those random values to integers based on the given limits in rand.randint(low, high). This mapping probably introduces an small overheard which is not to big to be a real problem if you do not call the function to often. But in your program, the function is called a lot (profiler says more than 4 million times), so the overhead sums up and becomes noteable.

There is no need to check for move==0 in the elif-part since you know the value can only be 0 or 1. Please use and and not the bitwise-and & when you concatenate booleans. See this SO question for a elaborate explenation of the differences

A note on numpy: I can not say for sure if there is a real performance difference using numpy instead of list for calculating the mean values etc.. I know from my experience, it has some seriously optimised algorithms that allow fast and numerically safe(r) computations on large arrays. Additionally, numpy allows convenient handling of list/arrays/matrices with more than one dimension. So in your case (without in-depth analysis) it basically comes down to personal preference and maybe convenience.

Source Link
AlexV
  • 7.4k
  • 2
  • 24
  • 47

Performance

I threw a profiling program at your code. The results showed, that most of the time is wasted on rand.randint(0, 1). Instead of calling rand.randint(0, 1) and checking for 0 and 1, use rand.random(). This will give you a random number in the interval \$ [0, 1)\$. Your condition will then become \$ < 0.5 \$. On my machine this reduced the time to run the code from about \10ドル\$-\12ドルs\$ to around \1ドル\$-\1ドル.5s\$, which is around an order of magnitude.

Code and style

Style

I don't know if there is a style requirement where you are writing this program, but in general, Python variable and function names should be all_lower_case (see the infamous PEP8).

Documentation

It is always nice to have at least a little documentation of the given functions. Especially since Python is an untyped language and maybe others (or a later version of you) finds the code anywhere and want to reuse it. Again there is a nice reference for Python (link).

Comparison operator###

There is no need to check for move==0 in the elif-part since you know the value can only be 0 or 1. Please use and and not the bitwise-and & when you concatenate booleans.

List comprehension

There is no real need to preallocate space with trials = [0] * 100. You should use a list comprehension instead

trials = [randomWalk(200) for _ in xrange(100)]

Result

I had a few moments of time, so I played a little bit with your code. I implemented the suggestions from my answer, added some documentation, introduced another function, added some variables and used numpy to have a litte bit of extra fun. The code I came up with is following.

import numpy as np
import random
def random_walk(x):
 """Simulate a single random walk"""
 position = 0
 steps = 0
 while (position != x):
 move = random.random()
 steps += 1
 if move < 0.5:
 position += 1
 elif position != 0:
 position -= 1 
 return steps
def random_walk_simulator(n_walks=100, walk_distance=200):
 """Simulate a bunch of random walks"""
 trials = np.array([random_walk(walk_distance) for _ in range(n_walks)])
 print("Mean # of steps: {:.2f}".format(trials.mean()))
 print("STD # of steps: {:.2f}".format(trials.std()))
 
if __name__ == '__main__':
 random_walk_simulator(100, 200)
lang-py

AltStyle によって変換されたページ (->オリジナル) /