實驗結論
- 如果需要在循環結束后獲得結果,推薦列表解析;
- 如果不需要結果,直接使用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獲得