亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 1255 | 回復: 0
打印 上一主題 下一主題

Python Optimization: extending with C [復制鏈接]

論壇徽章:
0
跳轉到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2009-10-20 16:19 |只看該作者 |倒序瀏覽

So, you want to code your project with your favourite language, which obviously :) is Python, and at the same time, you have some computationally heavy problem at your hand. But using Python for large calculations, for example, is not always preferred, because the interpreted nature of the language. Does this sound familiar?
Optimize, optimize...
One solution, of course, is to optimize your python code. This topic isn't covered here, but
here
is a link to great tips for optimizing python code. Other solution, is to make your problem solving algorithm more effective. This is one major aspect in making your program work faster.
But what if you have optimized your code already? And you are using the best algorithms which have been known to be the fastest, and still the program is slow like a turtle? Then, there is one solution (besides upgrading your computer) left: extend your program with C! (or C++) Use Python to code the other parts with comfort, and then, write the routines which take up the CPU time with C!
Case study: calculating primes
Let's say that you have a program, which needs to calculate the first n primes. (Why? Dunno, that's up to you. :) So, you write your code with python, the outcome might be something like this:
def isprime1(input):
    if input  1:
        if input%n == 0:
            return 0
        n = n - 1
    return 1
def main():
    i = 0
    l = 0
    max = int(sys.argv[1])
    while 1:
       
        if isprime1(i):
            l = l +1
        i = i + 1
        if l == max:
            break
    print max, "primes calculated"
   
if __name__ == "__main__":
    main()
The isprime1 function calculates if a given number is a prime number. I guess not the best 'algorithm' available, but that's not relevant here. Since Python is highly readable, no further comments for the code is required, right? :)
The program runs beautifully, but then, you notice that when the amount of calculated primes goes up, it starts to take enormously time. As we observe
later
, the equivalent C program runs something like 30 times faster! Whoah, wouldn't like to wait 30 times longer with our Python version. Here's the C code:
int isprime1(int input)
{
        int n;
        if (input  1){
                if (input%n == 0) return 0;
                n--;
        }
        return 1;
}
int main(int argc, char *argv[]){
        int i=0, l=0;
        int max;
       
        max = atoi(argv[1]);
       
        while (1) {
                if (isprime1(i)==1) {
                        l++;
                }
                i++;
                if (l==max){
                        break;
                }
        }
       
        printf("%i primes calculated\n",max);
}
Looks pretty much the same that the Python version.
Solution
So, what now? As I hinted before, we have to make the prime checking routine with C. First thought might be that it could help some, but not so much it would be significant. Guess again...
The comparisons
Let's take a look at some timings I made... Here the graph shows the time used to calculate first n primes.


As you can see, calculation with pure Python code starts to slow down much before the C version. And surprise surprise, the Python + C version of our program run nearly as fast as the pure C version! Very nice.
Here's a closer look to relation between the pure C version and the Python + C version of our program.


With large n, the difference between the C and the Python + C program becomes much smaller. Which is no other than good news for us! :)
The Extending
So, what is this extending business anyway and how do we do it? Basically, it's nothing more than writing a module to Python with C. The more into depth details and documentation of this process is described in
Python documents
, of course, but I'll give you a little example to whet your appitite. :)
Step 1
Decide what you want to code with C. In our case, the prime checking function is obviously the one we need to write with C, to get some speed up.
We have the code for that function ready, so now all we have to do is make it 'compatible' with Python. We'll name the new source file 'prmodule.c'. (I'll just show an example here, which is pretty much an imitation of that in Python documentation, except that we are calculating primes, so consult Python documentation for further information.)
The isprime function in prmodule.c:
static PyObject *pr_isprime(PyObject *self, PyObject *args){
        int n, input;
        if (!PyArg_ParseTuple(args, "i", &input))
          return NULL;
       
        if (input  1){
                if (input%n == 0) return Py_BuildValue("i", 0);;
                n--;
        }
        return Py_BuildValue("i", 1);
}
The function must return a PyObject pointer and it takes PyObject pointers' as parameters too. That's how we get the real arguments from python call. PyArg_ParseTuple() is used to parse the arguments passed from python. We parse a integer from parameter, which tells us what number is to be checked. When returning a value, we must pass it in python object, Py_BuildValue() is used for that purpose.
Pretty simple and straightforward, when you get the idea. Though, prmodule.c isn't quite finished yet. We need to tell what methods are available in our module and last, make a initialization method for the module.
So we add:
static PyMethodDef PrMethods[] = {
        {"isprime", pr_isprime, METH_VARARGS, "Check if prime."},
        {NULL, NULL, 0, NULL}
};
void initpr(void){
        (void) Py_InitModule("pr", PrMethods);
}
to the prmodule.c source file.
Step 2
Next, we need to compile our module. There's the nice distutils package which does pretty much all we need. Perhaps you've already seen those setup.py named files from some python libraries. That's what we need to do now. (We're not really installing anything anywhere, just compiling.)
Let's write the setup.py:
from distutils.core import setup, Extension
module = Extension('pr', sources = ['prmodule.c'])
setup(name = 'Pr test', version = '1.0', ext_modules = [module])
and run 'python setup.py build'. This should compile the module. That's it! The result can be found under build/lib.linux-i686-2.1 (or similar) directory, named 'pr.so'. You can copy it to your source directory, then use it like any other module. For example:
comet:~/prog/python/prime$ python
Python 2.1.3 (#1, Apr 20 2002, 10:14:34)
[GCC 2.95.4 20011002 (Debian prerelease)] on linux2
Type "copyright", "credits" or "license" for more information.
>>> import pr
>>> pr.isprime(17)
1
>>>


本文來自ChinaUnix博客,如果查看原文請點:http://blog.chinaunix.net/u/30686/showart_2074177.html
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復

  

北京盛拓優(yōu)訊信息技術有限公司. 版權所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關心和支持過ChinaUnix的朋友們 轉載本站內容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP