This is one example of a thread that was in need of some closure. After some time, I think I have figured it out. For anyone interested in doing something computationally intensive, but afraid to use
python because it would be too slow, this may prove to be a good solution.
I understand that linux users probably just have to snap their fingers to get boost.
python to work, but it was proving difficult under windows. Since I still feel some loyalty to windows, and I can't snap my fingers very well, I wanted to see if I could get it to finally work here.
Below are the steps that seem to make it work:
1. Boost is now up to 1.41, but it can still be built per the instructions here:
TUTORIAL: Boost 1.37.0 + QuantLib 0.9.6 and Visual Studio 2008
2. The build should create a few different boost.
python dlls.
3. This step is just for organization. Create a folder and place the dlls from step 2 there. Add this folder to the PATH and PYTHONPATH. If you don't want to create this folder, I think you could probably just add C:\boost\libs to the path. The important thing is that
python and the extensions you create down the road can see these libraries.
4. Create your extension as per the guidelines here:
Chapter*1.*python 2.0
The boost
python library basically uses a macro to wrap regular
c++ code into a
python module. So, you can use previously written code or libraries, and just wrap them up ( no need to change anything you might have written before ).
5. I use MSVC9.0, but whichever tool set you use, just make sure that your project builds to a shared library (dll), but change the output file to be a .pyd, which is just a renamed dll. All newer versions of
python look for pyd instead of dll extensions. If you created the file from step 3, put this pyd file in there. If not, then put this library somewhere in your path.
7. Invoke
python and run like you normally would. For example, I created the extension "boosthello_ext". The session goes as follows:
Code:
>>>import boosthello_ext
>>>print boosthello_ext.greet()
-> hello, boost
>>>
6. And Bob's your uncle. There is a remarkable increase in performance for intensive computations. I added a function to the above module that just loops over an inputted number. The results are below; run is the iteration number, num is the number of loops in the iteration,
python is how long it takes the interpreter to run, ext is how long it takes the boosthello module to run:
Code:
run 1; num: 1000000, python: 0.128761, ext: 0.001314
run 2; num: 2000000, python: 0.263353, ext: 0.002688
run 3; num: 3000000, python: 0.391827, ext: 0.003960
run 4; num: 4000000, python: 0.533130, ext: 0.005340
run 5; num: 5000000, python: 0.653911, ext: 0.006662
run 6; num: 6000000, python: 0.789581, ext: 0.008092
run 7; num: 7000000, python: 0.921839, ext: 0.009255
run 8; num: 8000000, python: 1.049060, ext: 0.010754
run 9; num: 9000000, python: 1.194949, ext: 0.012029
run 10; num: 10000000, python: 1.331470, ext: 0.013288
For reference, the helloboost code is below:
Code:
# include <boost/python.hpp>
char const* greet()
{
return "hello, boost";
}
double simulate( int num )
{
double sum = 0;
for ( int i = 0; i < num; i++ )
sum += i;
return sum / num;
}
BOOST_PYTHON_MODULE(boosthello_ext)
{
using namespace boost::python;
def("greet", greet);
def("sim", simulate);
}