forked from Advanced_Python/advanced-python-homework-2023
113 lines
3.5 KiB
Markdown
113 lines
3.5 KiB
Markdown
# Interpreters
|
|
|
|
## Results
|
|
![results](result.png)
|
|
|
|
### Observations
|
|
- Functions w/o Numpy in PyPy run **much faster**. JIT compilation optimizes the function's code and runs compiled versions of them $\Rightarrow$ improvement in time
|
|
- Entire file evaluation for PyPy takes **a bit longer**. This may be a drawback of JIT optimization
|
|
- [PyPy with Numpy is slow](https://stackoverflow.com/questions/42536308/why-is-pypy-slower-for-adding-numpy-arrays). Reason:
|
|
- Numpy is written in C
|
|
- PyPy's JIT compilation is not compatible with C
|
|
- Extra conversion is required (takes time)
|
|
- Numpy functions don't give a good improvement in perfomance. Possibly because the code uses classic Python loops instead of numpy vectorisation.
|
|
|
|
## Tested interpreters
|
|
- CPython 3.9
|
|
- CPython 3.11
|
|
- PyPy 3.9 latest
|
|
- Pyodide (did not test full file because it only runs in a browser)
|
|
- Xeus (again no full file)
|
|
## Failed to test
|
|
- PyPy 3.9 v5.7
|
|
- couldn't install numpy `Ignoring ensurepip failure: pip 9.0.1 requires SSL/TLS`
|
|
- error when testing with types:
|
|
```python
|
|
invalid syntax --> image: list[list[int]] = [[0 for i in range(qpoints)] for j in range(ppoints)]
|
|
```
|
|
- Jython (dependencies issues)
|
|
|
|
## Testing Code
|
|
- Tested functions code is in `./test_funcs` package
|
|
- File for testing function times: `test_func_only.py`
|
|
- Files for entire evaluation testing: `test_full_{func}.py`
|
|
- Bash script: `test_full.sh`
|
|
- Analysis file: `analyse.ipynb`
|
|
|
|
### Realisations of mandelbrot functions tested:
|
|
```python
|
|
def linspace(start, stop, n):
|
|
if n == 1:
|
|
yield stop
|
|
return
|
|
h = (stop - start) / (n - 1)
|
|
for i in range(n):
|
|
yield start + h * i
|
|
|
|
def mandelbrot_with_types(
|
|
pmin: float = -2.5,
|
|
pmax: float = 1.5,
|
|
qmin: float = -2,
|
|
qmax: float = 2,
|
|
ppoints: int = 200,
|
|
qpoints: int = 200,
|
|
max_iterations: int = 300,
|
|
infinity_border: float = 100) -> list[list[int]]:
|
|
|
|
image: list[list[int]] = [[0 for i in range(qpoints)] for j in range(ppoints)]
|
|
for ip, p in enumerate(linspace(pmin, pmax, ppoints)):
|
|
for iq, q in enumerate(linspace(qmin, qmax, qpoints)):
|
|
c: complex = p + 1j * q
|
|
z: complex = 0
|
|
for k in range(max_iterations):
|
|
z = z ** 2 + c
|
|
if abs(z) > infinity_border:
|
|
image[ip][iq] = 1
|
|
break
|
|
return image
|
|
|
|
def mandelbrot_no_types(
|
|
pmin=-2.5,
|
|
pmax=1.5,
|
|
qmin=-2,
|
|
qmax=2,
|
|
ppoints=200,
|
|
qpoints=200,
|
|
max_iterations=300,
|
|
infinity_border=100):
|
|
image = [[0 for i in range(qpoints)] for j in range(ppoints)]
|
|
for ip, p in enumerate(linspace(pmin, pmax, ppoints)):
|
|
for iq, q in enumerate(linspace(qmin, qmax, qpoints)):
|
|
c = p + 1j * q
|
|
z = 0
|
|
for k in range(max_iterations):
|
|
z = z ** 2 + c
|
|
if abs(z) > infinity_border:
|
|
image[ip][iq] = 1
|
|
break
|
|
return image
|
|
|
|
def mandelbrot_np(
|
|
pmin=-2.5,
|
|
pmax=1.5,
|
|
qmin=-2,
|
|
qmax=2,
|
|
ppoints=200,
|
|
qpoints=200,
|
|
max_iterations=300,
|
|
infinity_border=100):
|
|
image = np.zeros((ppoints, qpoints))
|
|
|
|
for ip, p in enumerate(np.linspace(pmin, pmax, ppoints)):
|
|
for iq, q in enumerate(np.linspace(qmin, qmax, qpoints)):
|
|
c = p + 1j * q
|
|
z = 0
|
|
for k in range(max_iterations):
|
|
z = z ** 2 + c
|
|
if abs(z) > infinity_border:
|
|
|
|
image[ip, iq] = 1
|
|
break
|
|
return image
|
|
```
|