CodeSnap 0.0.1 来啦!一个python小工具

想做这个东西很久了,前几天终于下定决心开始写代码,没想到一切进行的还挺顺利,第一个版本挺快就做出来了。

我相信每一个python(其实是任何语言)的开发者都和我一样,有一个经常出现的需求——想知道自己的程序到底在哪儿花的时间,从而进行针对性的优化。

python本身有一些还算不错的profiling工具,我之前也一直在用内置的cProfile。cProfile的整体功能还是令人满意的,但是有几个问题我一直耿耿于怀。

首先,cProfile的使用虽然算不上晦涩,但是也谈不上简单。把profile数据和显示分离在大型项目里是一个很常规的做法,但是在使用上总显得不那么直观。每次隔一阵没用再想用就得回去查一下到底怎么print_stats。

其次,cProfile的数据展示不太直观。如果你想揪出那个最耗时的函数,或许并不困难,但是如果你真的想了解你的代码是如何运行的,代码随着时间的走向如何,cProfile是没有这个能力的,cProfile最后展示的是经过了时间积累的结果。

于是乎,我受公司内部profiling tool的启发,想做一个小的visualization工具,弥补一些cProfile的弱项,这就是CodeSnap的起源。

简单的说,CodeSnap是一个轻量级的易用的profiling+visualization工具,从function entry/exit的角度让你知道你的程序随时间的变化和发展,从而找到可能优化的点(或者对程序的运行有更深刻的了解)。

说了这么多,先上一张图

我知道此时一定会有人说——好丑啊!

其实这就是程序员的审美:)

好吧我还没有那么长时间调整UI,不过我是真的觉得大概长成这样就可以了,至少满足我的需求了。

这张图展示的是不同的sort algorithm随着数据量增大的运行情况(github.com/akhof/Python)。横向坐标是时间,纵向是call stack。

我们zoom in一下

这是最后一个quick sort,熟悉quick sort的小伙伴应该能看到,每个quick sort下面前半部分的换位,然后接着两个recursion。这里就可以发现,第一个pivot运气不好,导致第一次分的很偏。

再换一个简单点的例子

我们知道fib有一个很蠢的recursive的写法,以及一个很常见的优化。

def fib(n):
    if n <= 1:
        return 1
    return fib(n-1) + fib(n-2)

def smart_fib(n, cache):
    if n <= 1:
        result = 1
    elif n in cache:
        return cache[n]
    else:
        result = smart_fib(n-1, cache) + smart_fib(n-2, cache)
        cache[n] = result
    return result

我们先后用这两个函数跑一个fib(13)感受一下。

结果大概长这样。可以看到,愚蠢版的fib经历了大量的无价值的recursion,而不那么愚蠢版的速度明显快非常多。

再试一个例子。很多人在python里喜欢把list直接当queue用,每次dequeue的时候就pop(0)一下。那pop(0)这个操作到底效率如何呢?我们做个实验。

def test_func():
    def list_pop_head(lst):
        lst.pop(0)
    def list_pop_tail(lst):
        lst.pop(-1)
    
    for i in [100, 1000, 10000, 100000, 1000000]:
        lst = [0] * i
        list_pop_head(lst)
        list_pop_tail(lst)

test_func()

虽然看的不是那么清晰,但是最后一个块还是能看出来,list_pop_head(死亡芭比粉色)的效率是远低于list_pop_tail的。

看的不那么清晰的原因是,我们在构建list的时候是花费了大量的时间的(中间青绿色下面没东西的部分)。

在写文章的过程中,版本号已经从0.0.1升级到了0.0.2(因为0.0.1不work……),在知乎就不写详细的用法了,大家想尝试的欢迎直接

pip install codesnap

github链接给出来,里面有详细的用法,project还在开发中,希望未来还有文章和大家见面,欢迎大家试用和提出宝贵意见~

gaogaotiantian/codesnapgithub.com图标

编辑于 08-06

文章被以下专栏收录