Preston,
Glad to hear you are interested in this.
Just to be clear, when I refer to "isapi-extension direct" in my tests,
it involved the Python interpreter. The code I used to test that is here:
https://gist.github.com/827989
Also, I did some tinkering with isapi_wsgi.py and figured out that the
main slow-down seems to be related to prepping the environ dict. Here
are my test files. Setup this way, any exceptions generated when
modifiying isapi-wsgi should come through to the browser for easier
debugging:
https://gist.github.com/828168
When I started off (no modifications to isapi-wsgi), I was getting ~900
reqs/sec. I then changed _run_app() to what is shown in the gist and
got ~1000 reqs/s. I then modified add_cgi_vars() and got ~1400
reqs/sec, which is just about even with my "isapi-extension" direct numbers.
So it looks to me like any performance improvement efforts should be
directed towards _run_app(), add_cgi_vars() and related environ
manipulations.
--------------------------------------
Randy Syring
Intelicom
Direct: 502-276-0459
Office: 502-212-9913
For the wages of sin is death, but the
free gift of God is eternal life in
Christ Jesus our Lord (Rom 6:23)
FWIW, the Python profiler should work fine in this environment, so long
as you are sure to send the output somewhere other than the non-existent
console. I just made a small change to the C code so the GIL isn't
acquired and released when fetching server variables as that would just
have added overhead for no gain (as no IO is performed during that
operation.) If the profiler shows this fetch to still be significant,
we could look at the option of adding a method to allow multiple
variables to be fetched at once - but the profiler should tell us if
that is worthwhile.
Cheers,
Mark
I managed to do that by "faking" the IIS part of the server with FakeECB:
https://gist.github.com/828716
and then running the profiler. That should give a "pure" profile of
just isapi-wsgi, but it seems like it would be better to have the
profiling done with real requests through IIS. Any suggestions on how I
should go about doing that?
--------------------------------------
Randy Syring
Intelicom
Direct: 502-276-0459
Office: 502-212-9913
For the wages of sin is death, but the
free gift of God is eternal life in
Christ Jesus our Lord (Rom 6:23)
Did you try attaching the profile to __ExtensionFactory__? I think that's the highest level function.
While profiling across multiple page views would be helpful, in practice it may be tough to do that. Finding the right place to call the profiler is a problem, but also knowing when to cut off and dump out the profile. It may be tough to do that with the function decorator I provided since it's pretty simple.
Did you see anything interesting in the profiles of single page views?
-------------------------------------- Randy Syring Intelicom Direct: 502-276-0459 Office: 502-212-9913 For the wages of sin is death, but the free gift of God is eternal life in Christ Jesus our Lord (Rom 6:23)
I have been working on profiling some Python in classic ASP which
suffers from the a similar issue with the lifetime of the profile
(i.e. wanting to get multiple requests). I have had some success with
a module that has the following:
_profiler = None
def start_profiler():
"""Start the profiler, needs to happen every request in
classic asp because
it seems like the profiler is stopped after each request"""
global _profiler
if not _profiler:
from cProfile import Profile
_profiler = Profile()
_profiler.enable()
def stop_profiler():
"""Stop the profiler on some specific in request cue like
Profile=Stop query param.
I do this as the last thing in the request"""
global _profiler
_profiler.dump_stats(r'c:\well\known\path.prof')
_profiler = None
The trick here is the low level (not documented) .enable() method. The
dump_stats method calls the .disable() method of the profiler. I still
have to look at the code for _lsprof.Profile (the base class for
cProfile to ensure that enable and disable maintain the current
profile information when called multiple times.
PyISAPIe which has done some performance optimization work and the
author specifically calls out attempting to do more of the boiler
plate WSGI work in C and without GIL (which probably doesn't much come
into play in sequential requests but will play heavily into concurrent
ones): http://sourceforge.net/apps/trac/pyisapie/wiki/ReleaseInfo &
http://sourceforge.net/apps/trac/pyisapie/wiki/WikiStart (in both
cases search for GIL).
If you are using 2.6 or lower, I would also try using psyco. I found
that helped a lot with the speed (doubling or tripling my requests per
second (in asp not isapi calls). My profiling showed that a lot of
time was spent transitioning between python and other languages in
asp.
I am wondering if the benchmark from the OP is more than a little
suspect. If the goal of your app is to export a static string, then
all the effort spent to convert the the environment info up front is
wasted. Any benchmark that compares effort spent to do nothing to no
effort spent to do nothing is always going to show the former as being
slower than the latter.
Is it worth getting the environment data lazily? Is it worth making a
Cython extension to do it faster? Can we make a C extension to do some
of the work of extracting the info from the ecb with the GIL released?
When first looked at isapi-wsgi, PyISAPIe did not have wsgi support.
Now it does and it looks mature, I am wondering what the advantage of
isapi-wsgi is over PyISAPIe at this point? Note, I am not saying there
isn't an advantage, I am just asking what people think the advantage
is?
I am also wondering (given the advances in PyPy lately) whether
isapi-wsgi can use PyPy instead. That could potentially be an
advantage for this use case, since the free threading allowed by PyPy
*should* allow higher levels of concurrency. Also PyPy has a jit for
x64, something for which there is no support in CPython.
-Chris
--
Christopher Lambacher
ch...@kateandchris.net
> Is it worth getting the environment data lazily? Is it worth making a
> Cython extension to do it faster? Can we make a C extension to do some
> of the work of extracting the info from the ecb with the GIL released?
>
In a previous post on this thread. Mark Hammond mentioned he has made
a change to the C code so the GIL isn't acquired and released when
fetching server variables. It would be interesting to see if this has
improved the benchmarking results.
A quick look at the profile data sent before implies to me that it will
not make much difference - but I guess the proof is in the pudding!
FWIW, I just released build 215 of pywin32 which has that change, so now
it can be measured...
Cheers,
Mark