zoukankan      html  css  js  c++  java
  • [Python3]为什么map比for循环快

    实验结论

    • 如果需要在循环结束后获得结果,推荐列表解析;
    • 如果不需要结果,直接使用for循环, 列表解析可以备选;
    • 除了追求代码优雅和特定规定情境,不建议使用map

    如果不需要返回结果

    这里有三个process, 每个任务将通过增加循环提高时间复杂度

    	def process1(val, type=None):
    	    chr(val % 123)
    
    	def process2(val, type):
    	    if type == "list":
    	        [process1(_) for _ in range(val)]
    	    elif type == "for":
    	        for _ in range(val):
    	            process1(_)
    	    elif type == "map":
    	        list(map(lambda _: process1(_), range(val)))
    
    	def process3(val, type):
    	    if type == "list":
    	        [process2(_, type) for _ in range(val)]
    	    elif type == "for":
    	        for _ in range(val):
    	            process2(_, type)
    	    elif type == "map":
    	        list(map(lambda _: process2(_, type), range(val)))
    

    然后通过三种循环方式,去依次执行三种任务

    	def list_comp():
    	    [process1(i, "list") for i in range(length)]
    	    # [process2(i, "list") for i in range(length)]
    	    # [process3(i, "list") for i in range(length)]
    
    	def for_loop():
    	    for i in range(length):
    	        process1(i, "for")
    	        # process2(i, "for")
    	        # process3(i, "for")
    
    	def map_exp():
    	    list(map(lambda v: process1(v, "map"), range(length)))
    	    # list(map(lambda v: process2(v, "map"), range(length)))
    	    # list(map(lambda v: process3(v, "map"), range(length)))
    



    从上述的图像中,可以直观的看到, 随着任务复杂度的提高以及数据量的增大,每个循环完成需要的时间也在增加,
    但是map方式花费的时间明显比其他两种要更多。 所以在不需要返回处理结果时,选择标准for或者列表解析都可以。

    因为标准for循环和列表解析方式在循环任务复杂度逐渐提高的情况下,处理时间基本没有差异。

    需要返回结果

    这里有三个task, 每个任务将通过增加循环提高时间复杂度

    	def task1(val, type=None):
    	    return chr(val % 123)
    
    	def task2(val, type):
    	    if type == "list":
    	        return [task1(_) for _ in range(val)]
    	    elif type == "for":
    	        res = list()
    	        for _ in range(val):
    	            res.append(task1(_))
    	        return res
    	    elif type == "map":
    	        return list(map(lambda _: task1(_), range(val)))
    
    	def task3(val, type):
    	    if type == "list":
    	        return [task2(_, type) for _ in range(val)]
    	    elif type == "for":
    	        res = list()
    	        for _ in range(val):
    	            res.append(task2(_, type))
    	        return res
    	    elif type == "map":
    	        return list(map(lambda _: task2(_, type), range(val)))
    

    然后通过三种循环方式,去依次执行三种任务

    	def list_comp():
    	    # return [task1(i, "list") for i in range(length)]
    	    return [task2(i, "list") for i in range(length)]
    	    # return [task3(i, "list") for i in range(length)]
    
    	def for_loop():
    	    res = list()
    	    for i in range(length):
    	        # res.append(task1(i, "for"))
    	        res.append(task2(i, "for"))
    	        # res.append(task3(i, "for"))
    	    return res
    
    	def map_exp():
    	    # return list(map(lambda v: task1(v, "map"), range(length)))
    	    return list(map(lambda v: task2(v, "map"), range(length)))
    	    # return list(map(lambda v: task3(v, "map"), range(length)))
    



    从上述的图像中,可以直观的看到, 随着任务复杂度的提高以及数据量的增大,每个循环完成需要的时间也在增加,
    但是明显看出, 使用list_comp列表解析在, 循环需要返回处理结果的每次任务中都表现的很好,基本快于其他两种迭代方式。

    而标准for循环和map方式在循环任务复杂度逐渐提高的情况下,处理时间基本没有差异。

    为什么普遍认为map比for快?

    我认为可能跟处理的数据量有关系,大部分场景下,使用者只测试了少量的数据(100W以下,比如这篇文章,就是数据量比较少,导致速度的区别不明显),在少量的数据集下,我们确实看到了map方式比for循环快,甚至有时候比列表解析还稍微快一点,但是当我们逐渐把数据量增加原来的100倍,这时候差距的凸现出来了。

    如上图,在小数据集上(100W-1KW之间), 三者消耗的时间差不多相等,但是用map方式遍历和处理,还是有一定的加速优势。
    具体实验代码可以通过Github获得

  • 相关阅读:
    【笔记】DSP程序烧写问题
    图解DotNet框架之二:System
    图解DotNet框架之一:编译与执行引擎(下)
    图解DotNet框架之四:System.Data
    图解DotNet框架之九:WPF
    图解DotNet框架之十:WCF(Remoting,Webservice)
    图解DotNet框架之一:编译与执行引擎(上)
    图解DotNet框架之六:System.XML
    反射手册笔记 2.程序集,对象和类型
    图解DotNet框架之三:System.IO
  • 原文地址:https://www.cnblogs.com/sight-tech/p/12987276.html
Copyright © 2011-2022 走看看