鳕鱼剖面分析

2024-10-01 22:28:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下Cython代码:

# cython: profile=True
import cProfile
from cython import parallel
from libc.stdio cimport FILE, fopen, fclose, fwrite, getline, printf
from libc.string cimport strlen
from libcpp.string cimport string
cdef extern from "stdio.h" nogil:
   int mkstemp(char*);

cdef run_io(string obj):
    cdef int i, dump
    cdef size_t len_ = 0
    cdef char* fname = "/tmp/tmpc_XXXXXX"
    cdef char* nullchar = NULL
    cdef char* line = NULL
    cdef string content = b""
    cdef FILE* cfile
    for i in range(10000):
        dump = mkstemp(fname)
        cfile = fopen(fname, "wb")
        fwrite(obj.data(), 1, obj.size(), cfile)
        fclose(cfile)
        cfile = fopen(fname, "rb")
        while True:
            if getline(&line, &len_, cfile) == -1:
                break
            else:
                content.append(line)
        fclose(cfile)

def run_test():
    cdef string obj = b"abc\ndef"
    cProfile.runctx("run_io(obj)", globals(), locals())

当我试图从python3控制台运行它时,我得到一个错误:

^{pr2}$

如果我将run_io函数cdef的定义改为def,它会起作用:

         7 function calls in 2.400 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    2.400    2.400 <string>:1(<module>)
        2    0.000    0.000    0.000    0.000 stringsource:13(__pyx_convert_string_from_py_std__in_string)
        1    2.400    2.400    2.400    2.400 testc2.pyx:10(run_io)
        1    0.000    0.000    2.400    2.400 {built-in method exec}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
        1    0.000    0.000    2.400    2.400 {test.run_io}

但是,这并不是很有用,因为我只看到整个函数的总运行时(我希望看到生成文件名、读取、写入等的部分运行时)。在

因此,我有两个问题:

  1. 是否可以分析Cython函数(用cdef定义)?如果是,怎么办?

  2. 如何使分析更具信息量(即测量每个被调用函数所花费的时间)?


Tags: 函数runinfromioobjstringline
1条回答
网友
1楼 · 发布于 2024-10-01 22:28:31

python和cpython评测是确定性的,这意味着它们通过捕捉函数进入和退出时的壁时间来工作,但仅限于探查器被要求评测的函数。 它们不能提供逐行计时信息,除非它们还捕捉每行代码前后的时间。在

如果你不介意放弃测量精度的话,一种获取逐行信息的方法是采集少量的堆栈样本。每一行代码都有inclusive time(cumtime)作为总时间的一部分,而这正是它在堆栈上的时间的分数。所以当你取一个堆栈样本时,这个分数就是你看到它的概率。如果您查看10到20个示例,您就可以很好地了解哪些代码行需要花费大量时间。Here's an example.

:)我有时听到的反对意见是“这样做不会完全减慢程序的速度并使结果无效?”好吧,好好想想。有一行代码,它需要一小部分时间,比如36.5%,所以它在堆栈中只占那部分时间。9秒后再看程序堆栈。有36.5%的几率这条线在堆栈上。现在,门铃响了,一个星期后你才回来看。这一周的延迟是否会改变这条线在堆栈样本上的概率? 当然不是。 电脑很有耐心。不管您花多长时间查看堆栈样本,它都是不变的。在

相关问题 更多 >

    热门问题