'Why is pypy flask aplication slower than cpython?
I have a flask application (app.py) which returns a string,
from flask import Flask
import os
app = Flask(__name__)
@app.route("/")
def hello():
return "Flask inside Docker!!"
if __name__ == "__main__":
port = int(os.environ.get("PORT", 6000))
app.run(debug=True,host='0.0.0.0',port=port)
I ran this application using the below dockerfile content, which gave me the throughput of 320/sec
FROM opensuse/leap:15.3
RUN zypper -n install python3 python3-pip python3-Flask
COPY . /app
WORKDIR /app
ENTRYPOINT ["python3"]
CMD ["app.py"]
However with pypy3, I got only 200/sec throughput, the docker file is given below.
FROM opensuse/leap:15.3
FROM pypy:3
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
ENTRYPOINT ["pypy3"]
CMD ["app.py"]
where requirements.txt contains only "flask".
What could be the reason for this performance degradation?
Solution 1:[1]
Two things comes to mind.
- It could be that running a basic app that just return a string doesn't really make use of pypy JIT compilation and other pypy optimizations. And in this specific case pypy interpreter is running slower
- Are you wrapping flask with gunicorn? if so and even if you dont, could it be that you set it up in a way that each invocation is executed in a new process? If each invocation is a new process, pypy JIT warmup is lost between each invocation, which means JIT is basically not working and you are just paying high price of pypy trying to JIT.
Solution 2:[2]
Brushing aside the fact that PyPy might really be intrinsically slower for your case, there are some factors that could be making it unnecessarily slower:
- Profiling is known to slow
PyPya lot more thanCPython. - Some debugging/logging code can disable optimizations (by, e.g., forcing frames).
- The server you're using can be a dominant factor in performance (think about how awful classic CGI would be with a JIT: it would never warm up). It can also simply influence results (different WSGI servers have shown various speed-ups).
- Old-style classes are slower than new-style ones.
- Even if everything is in memory, you could be hitting e.g. slow paths in PyPy's SQLite.
A nightly build will probably be faster too, as there are many improvements relative to 1.5.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Eitan |
| Solution 2 | Hammam Abo Jamous |
