python中嵌入C语言脚本

来源:互联网 发布:机器人语音聊天软件 编辑:程序博客网 时间:2024/05/16 12:41

借助Cinpy和C语言解释器TinyCC,可以在python程序里面直接嵌入C语言片断、不经编译直接使用C编写的函数了。

win2k平台上,简单的测试对比数据如下(递归方法计算第四十项兔子数列fib(40))

语言

实现

时间
(单位:秒)

python官方python 2.4.3纯python fib函数568.718天啊使用psyco加速的python fib函数17.922比较接近,还行使用swig直接转换的C语言编写的模块13.453使用Cinpy嵌入fib函数11.532     CVC6速度优化编译的可执行文件5.562 TinyCC 0.9.23编译的可执行文件6.719 解释执行6.813      FreeBASICfbc 0.16b编译的可执行文件(-arch 486)8.022 编译的可执行文件(-arch 686)7.619      forth4th 3.5a24th cx fib.4th277 这个表现太失望了 4th csv fib.4th fib.hx
4th lx fib.hx 1964th lg fib.hx fib.c
mingw -O2 fib.c -o fib.exe 110gforth-0.6.2Gforth-fast fib.gfth14.719不错,不过不是说和C的速度可以比嘛?
怎么也就是优化的python的速度啊

 

注:

  1. 其余源程序
    • freebasic
      function fib(x as integer) as integerif x<=1 thenreturn 1elsereturn fib(x-1) + fib(x-2)end ifend functiondim starttime, endtime as doubledim res as integerstarttime=timerres=fib(40)endtime=timerprint "fib(40)= ";resprint "time elapsed: "; (endtime-starttime); " s"      
    • 4th 
      : fib ( x -- y )dup 2 > ifdup  1 - recurseswap 2 - recurse +exitthendrop 1 ;time41 fib . crtimeswap -." time elapsed " . ." s" cr
    • gforth-0.6.2
      : fib ( x -- y ) dup 2 > if dup  1 - recurse swap 2 - recurse +  exit then drop 1 ;utime41 fib . crutime2swap d- ." time elapsed " d. ." us" cr

     

  2. 如果在windows下使用mingw编译当前的TinyCC,嵌入C脚本会报错:
    tcc: file '/c/Program Files/tcc/libtcc1.a' not found

    Doug Currie在tcc的邮件列表里面提供了一个补丁:

    Here is what I did (and reported to the mailing list) last February,
    so the patch may not be accurate for more recent versions, but the
    issues are the same...

    I have been able to create a libtcc.dll for WinXP using MinGW/MSYS;
    the changes that were necessary were very minor. Perhaps this
    description will help others use libtcc on Windows.

    First, a small bug to report:

    In tcc.c the function tcc_basename() follows the line:

    #if !defined(LIBTCC)

    but the function tcc_basename() is used in pe_build_exports() in
    tccpe.c -- moving the #if line below the function tcc_basename()
    eliminates a link error building libtcc.dll in PE target mode.

    Second, configuring and making tcc with MSYS places a pathname in
    config.h in MSYS format. For example, I passed the argument

    --prefix=/c/Dev/tcc

    to configure; this path was good for building tcc.exe and didn't
    contain any spaces, unlike the default path. This creates the line

    #define CONFIG_TCCDIR "/c/Dev/tcc"

    in config.h. Manually changing this line to

    #define CONFIG_TCCDIR "C:/Dev/tcc"

    enables libtcc.dll to find the include files and libraries once the
    library is built. [The application tcc.exe avoids this problem by
    setting tcc_lib_path from the application's directory at startup. A

    similar solution could be used for the library using DllMain.]

    So, after configure, fix CONFIG_TCCDIR in config.h and make.


    Finally, the library libtcc.dll can be built with the MSYS command:

    gcc -O2 -shared -Wall -Wl,--export-all-symbols /
    -mpreferred-stack-boundary=2 /
    -march=i386 -falign-functions=0 -fno-strict-aliasing /
    -DTCC_TARGET_PE -DLIBTCC -o libtcc.dll tcc.c

    Below is a diff of tcc-0.9.23 tcc.c and the changes for LIBTCC with
    TCC_TARGET_PE and DLL location of library files.

    Regards,

    e


    $ diff -u ../tcc-0.9.23-o/tcc.c tcc.c
    --- ../tcc-0.9.23-o/tcc.c       Fri Jun 17 18:09:15 2005
    +++ tcc.c       Tue Feb 28 17:03:44 2006
    @@ -10157,8 +10157,6 @@
                         flag_name, value);
     }

    -#if !defined(LIBTCC)
    -
     /* extract the basename of a file */
     static const char *tcc_basename(const char *name)
     {
    @@ -10175,6 +10173,35 @@
         return p;
     }

    +#if defined(LIBTCC)
    +
    +#ifdef WIN32
    +int __stdcall DllMain(void * hinstDLL, unsigned long fdwReason, void *
    lpvReserved)
    +{
    +    if (fdwReason == 1/*DLL_PROCESS_ATTACH*/)
    +    {
    +    /* on win32, as implemented in main()
    +       we suppose the lib and includes are at the location of this library
    +    */
    +        static char path[1024];
    +        char *p, *d;
    +
    +        GetModuleFileNameA(hinstDLL, path, sizeof path);
    +        p = d = strlwr(path);
    +        while (*d)
    +        {
    +            if (*d == '//') *d = '/', p = d;
    +            ++d;
    +        }
    +        *p = '/0';
    +        tcc_lib_path = path;
    +    }
    +    return 1 /*TRUE*/;
    +}
    +#endif
    +
    +#else /* !LIBTCC */
     static int64_t getclock_us(void)
     {
     #ifdef WIN32

原创粉丝点击