len(list(iterator)) और sum(1 for _ in iterator) में क्या अंतर है? इसके बाद, एक पुनरावर्तक की लंबाई की गणना करने के लिए उपयोग करने के लिए सबसे अच्छा कौन सा है?

1
Imad 9 जुलाई 2020, 18:15

2 जवाब

सबसे बढ़िया उत्तर

पहला ओ (एन) स्पेस का उपयोग करता है, क्योंकि इसे सूची बनाना है। दूसरा ओ (1) स्पेस का उपयोग करता है, क्योंकि रनिंग टोटल अपडेट होने के बाद उसे किसी तत्व को याद रखने की जरूरत नहीं है।

कोई भी बहुत उपयोगी नहीं है, क्योंकि आपने उनमें से किसी को भी देखे बिना मूल इटरेटर से प्रत्येक तत्व को त्याग दिया है। आपके पास इटेटरेटर कितने समय तक था बचा है। मान लें कि आप इसके साथ ठीक हैं, ओ (1) स्पेस ओ (एन) से बेहतर है।

5
chepner 9 जुलाई 2020, 18:19

जबकि मैं चेपनर के तर्क के साथ बहस नहीं कर सकता, कम से कम समय के संदर्भ में एक त्वरित बेंचमार्क विपरीत निष्कर्ष उत्पन्न करता है।

import time

def option1(a):
    return len(list(a))

def option2(b):
    return sum(1 for _ in b)

start = time.time()
for i in range(20000):
    a0 = range(1, 10000)
    a = option1(map(lambda x: x + 1, a0))
end = time.time()
print("Option 1:", end - start, "seconds")

start = time.time()
for i in range(20000):
    a0 = range(1, 10000)
    a = option2(map(lambda x: x + 1, a0))
end = time.time()
print("Option 2:", end - start, "seconds")

आउटपुट:

Option 1: 14.580924987792969 seconds
Option 2: 19.70468544960022 seconds

तो, कम से कम समय के संदर्भ में, दूसरा विकल्प 35% धीमा है (जैसा कि मैं पुनरावृत्तियों की लंबाई बढ़ाता हूं, पहला विकल्प थोड़ा खराब होता है, लेकिन ज्यादा नहीं)। यह भी ध्यान देने योग्य है कि कोई जनरेटर और कोई मध्यवर्ती सूची के साथ सीधे अनिवार्य समाधान, यानी।

def option3(c):
    i = 0
    for _ in c:
        i += 1
    return i

विकल्प 2 की तुलना में केवल थोड़ा बेहतर प्रदर्शन करता है, उपरोक्त कोड के समान इनपुट पर 18.61347 सेकंड देता है।

तो संक्षेप में, ऐसा लगता है कि सूची को मजबूर करना वास्तव में कुछ तेज़ है, बशर्ते आपके पास मध्यवर्ती सूची तैयार करने की जगह हो। मैंने इसे 50,000 तत्वों तक के पुनरावृत्तियों के साथ परीक्षण किया, और यह अभी भी जनरेटर-आधारित समाधान से बेहतर प्रदर्शन कर रहा है।

1
Silvio Mayolo 9 जुलाई 2020, 18:32