首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python中多个测试用例的时序分析

Python中多个测试用例的时序分析
EN

Code Review用户
提问于 2013-07-11 15:35:22
回答 1查看 1K关注 0票数 8

我正在学习Python中的时间分析。在指出time模块用于时序分析时,我使用了timeit模块。

我对时序分析的主要重点是对相同功能的两个变体进行多个测试用例。在这个示例代码中,我使用了两个函数变体来逆转一个数字。

时间分析能做得更好吗?该方法对于许多测试用例是可扩展的吗?

代码语言:javascript
复制
def reverse_num(num):
    '''returns the reverse of an integer '''
    if num < 0:
        return  - int(str(-num)[::-1])
    else:
        return  int(str(num)[::-1])

def reverse_num2(num):
    rev = 0
    while num > 0:
        rev *= 10
        rev += num % 10
        num /= 10
    return rev


if __name__ == "__main__":
    from timeit import Timer
    def test(f):
        for i in xrange(1000):
            f(i)

    print Timer(lambda: test(reverse_num)).timeit(number = 100)
    print Timer(lambda: test(reverse_num2)).timeit(number = 100)

我正在为我的timeit模块的使用发布示例测试运行,以便为下面的代码计时。我为这个问题写的。

代码语言:javascript
复制
def mysort(words):
    mylist1 = sorted([i for i in words if i[:1] == "s"])
    mylist2 = sorted([i for i in words if i[:1] != "s"])
    list = mylist1 + mylist2
    return list

def mysort3(words):
    ans = []
    p = ans.append
    q = words.remove
    words.sort()
    for i in words[:]:
        if i[0] == 's':
            p(i)
            q(i)
    return ans + words

def mysort4(words):
    ans1 = []
    ans2 = []
    p = ans1.append
    q = ans2.append
    for i in words:
        if i[0] == 's':
            p(i)
        else:
            q(i)
    ans1.sort()
    ans2.sort()
    return ans1 + ans2

def mysort6(words):
    return ( sorted([i for i in words if i[:1] == "s"]) +
              sorted([i for i in words if i[:1] != "s"])
             )

if __name__ == "__main__":
    from timeit import Timer
    def test(f):
        f(['a','b','c','abcd','s','se', 'ee', 'as'])

    print Timer(lambda: test(mysort)).timeit(number = 10000)
    print Timer(lambda: test(mysort3)).timeit(number = 10000)
    print Timer(lambda: test(mysort4)).timeit(number = 10000)
    print Timer(lambda: test(mysort6)).timeit(number = 10000)

计时结果如下

================================重启================================ >>> 0.0643831414457 0.0445699517515 0.0446611241927 0.0616633662243 >>> ================================重启================================ >>> 0.0625827896417 0.045101588386 0.0443568108447 0.0443568108447 ================================重新启动================================ >>> 0.0647336488305 0.0596154305912 0.0445711673841 0.0614101094441 0.06141094434 >>> ================================重新启动================================ >>> 0.0689924148581 0.0502542495475 0.0443466805735 0.0903234506 0.09001730656 0.0443794415 0.0835670386907 en20 20 en22#0.06756121379 0.050799814 0.04417814 0.04417854 0.068103000978 en20 20 0.06756121379 0.050799814 0.04417814 0.0681030978

正如您所看到的,结果每次都不同。我知道时间很小,但这是number = 10000timeit中的全部目的,就是通过多次计时和寻找平均或最好的时间来持续地进行测量。

在大多数情况下,第二个函数比第三个函数要花费更多的时间,但有时不需要。在某些情况下,第四个函数比第一个函数花费更多的时间,有时更少。

我认为这是正确的,根据使用,但为什么这些变量的结果?这是做时间安排的正确方法吗?我真的很困惑。

经过聊天室的一些讨论和一些思考之后,我想出了测试具有整数输入的函数的方法。可以为更多的测试定义额外的嵌套函数,并且可以进行更多的重复。这可能需要一段时间,但据我所知,效果很好。对于同一个函数的变体,需要添加简单的函数调用。

代码语言:javascript
复制
def testing():
    from timeit import Timer
    import random

    def tests(f, times):
        def test1(f):
            f(random.randint(1, 1000))
        def test2(f):
            f(random.randint(100000, 1000000))

        print(f.__name__)
        print(Timer(lambda: test1(f)).timeit(number = times))
        print(Timer(lambda: test2(f)).timeit(number = times//10))
        print()

    tests(reverse_num, 10000)
    tests(reverse_num2, 10000)

请注意,我是在讨论这个问题时开始使用Python 3的。我不会使用任何特定于Python 3的代码,所以所有代码都可以在Python2上运行,任何想要运行新代码的人只需更改print语句即可。没别的了。

EN

回答 1

Code Review用户

回答已采纳

发布于 2013-07-18 05:43:31

软件定时基准是出了名的噪音,因为你的计算机不是一个很好的控制实验平台。

  • 有些算法是不确定的。例如,一些快速排序实现选择了一个随机的枢轴元素。
  • 在运行基准测试时,您的python进程可能会被其他正在运行的应用程序、操作系统线程等抢占。
  • 即使您的进程在每次运行期间获得了相同数量的CPU,时间也可能有所不同,因为不同的应用程序组合正在运行,因此您的处理器的内存缓存有不同的命中/错过模式。
  • 有些运行可能比其他运行得到更好的分支预测。 (同样,由于其他正在运行的进程的混合)。这将导致更多的管道堵塞。

我会怀疑我给出的效果是按强度递减的顺序给出的(除了我相信Python的排序算法是确定性的,所以第一个效果不是这里的一个因素)。我还怀疑我只是擦破了表面。

编辑:

好的,为了逆转一个数字,假设您的典型输入是5位,那么您可以使用它。

代码语言:javascript
复制
if __name__ == "__main__":
    from timeit import Timer
    import random
    def test(f):
        f(random.randint(10000,99999))

    print Timer(lambda: test(reverse_num)).timeit(number = 10000000)
    print Timer(lambda: test(reverse_num2)).timeit(number = 10000000)
票数 6
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/28373

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档