From: Paul K. <Pau...@ni...> - 2011-11-23 10:53:54
|
>> I conclude that pycxx is only for the aim "to write python exteison in C++ easily", but not for the aim "to speed up the original pure python program". Am I right? Not really. You can make a Python program run faster if you translate a resource-heavy Python function into C++, wrap it in a Python wrapper, then call it from Python. But you have to arrange to call it only once, not thousands of times, because the speedup you get from translating the code into C++ will be completely lost if you have to pay the pycxx overhead thousands of times. The problem is not the speed of the translated code. The problem is the number of times you are calling it. When your code computes fib(10) and returns the value 89, the function fib() gets called 177 times. That's okay. But when your code computes fib(30) and returns the value 1,346,269 that is not okay, because the function fib() gets called 2,692,537 times. It doesn't matter how much faster the C++ verion of fib() is, because any saving is dwarfed by the huge function call overhead. Your C++ code is calling the Python function, which in turn is calling back to the C++ function. That is very expensive, and you are doing it millions of times. Why is your C++ function calling back to the Python function? The whole point of the exercise is to do the computation in C++, because that is the only way you are going to get a speedup. There are two ways to eliminate the problem. 1. Have your C++ function fib() call a C++ function cfib(), not the Python function fib(). Do the computation entirely in C++ and only return the value to Python when you are done. Don't route intermediate results via the pycxx interface. Like this: if (res<=Py::Long(1)) return Py::Long(1); else{ return Py::Long(cfib(res-2)+cfib(res-1)); } 2. Rewrite fib() as a nonrecursive function. Here's a sample Python function that runs in linear time and caches its results so that repeated calls are free: def fibseries(n, seed=[0,1]): while n > len(seed) - 2: seed.append(sum(seed[-2:])) return seed def fib(n, series=[0,1]): series = fibseries(n, series) return series[n+1] Implement that in C++ (which admittedly is a bit challenging) and you should see a modest improvement. But again, you must implement both functions in pure C++. No calling back to Python allowed. If your recursive C++ code is deliberately calling back to Python because there is some aspect of the algorithm you are finding hard to implement in C++ (integers bigger than 2**31-1, perhaps?), then your code is not a good candidate for migration to C++. That doesn't mean you can't get a speedup by migrating Python code to C++. You can. But not if your C++ code cheats by calling back into Pytnon. The information contained in this e-mail is confidential and may be privileged. It may be read, copied and used only by the intended recipient. If you have received it in error, please contact the sender immediately by return e-mail. Please delete this e-mail and do not disclose its contents to any person. NIBC Holding N.V. nor its subsidiaries accept liability for any errors, omissions, delays of receipt or viruses in the contents of this message which arise as a result of e-mail transmission. NIBC Holding N.V. (Chamber of commerce nr. 27282935), NIBC Bank N.V. (Chamber of commerce nr. 27032036) and NIBC Investment Management N.V. (Chamber of commerce nr. 27253909) all have their corporate seat in The Hague, The Netherlands. De informatie in dit e-mailbericht is vertrouwelijk en uitsluitend bestemd voor de geadresseerde. Wanneer u dit bericht per abuis ontvangt, gelieve onmiddellijk contact op te nemen met de afzender per kerende e-mail. Wij verzoeken u dit e-mailbericht te Vernietigen en de inhoud ervan aan niemand openbaar te maken. NIBC Holding N.V. noch haar dochterondernemingen aanvaarden enige aansprakelijkheid voor onjuiste, onvolledige dan wel ontijdige overbrenging van de inhoud van een verzonden e-mailbericht, noch voor door haar daarbij overgebrachte virussen. NIBC Holding N.V. (KvK nr. 27282935), NIBC Bank N.V. (KvK nr. 27032036) en NIBC Investment Management N.V. (KvK nr. 27253909) zijn statutair gevestigd te Den Haag, Nederland. |