2014-04-08 22 views
5

Tôi đã đoạn mã sau bằng Python:Python Generator đó mang lại kết quả nhiều hơn mất nhiều thời gian để tạo ra

import time 
import sys 

def returnlist(times): 
    t = time.time() 
    l = [i for i in range(times)] 
    print "list: {}".format(time.time() - t) 
return l 

def returngenerator(times): 
    t = time.time() 
    g = (i for i in range(times)) 
    print "generator: {}".format(time.time() - t) 
    return g 

g = returngenerator(times) 
l = returnlist(times) 

1.For lần = 1000000 tôi nhận được kết quả:

máy phát điện: ,107323884964

danh sách: 0,225493192673

2. Đối với lần = 10000000 tôi nhận được :

máy phát điện: 0,856524944305

danh sách: 1,83883309364

Tôi hiểu tại sao trong danh sách thứ 2 sẽ mất nhiều thời gian để tạo ra nhưng tại sao các máy phát điện thứ 2 sẽ mất thời gian hơn không? Tôi giả định rằng do đánh giá lười biếng, nó sẽ mất khoảng thời gian để tạo ra máy phát điện thứ nhất.

Tôi đang chạy chương trình này trên một Ubuntu VM

+4

Bạn có đang chạy Python 2 không? Nếu đúng như vậy, hãy sử dụng 'xrange' thay vì' dải ô'. – Carsten

+0

@Carsten là hoàn toàn đúng, lý do điều này là chậm hơn trong python-2 là 'phạm vi' chỉ trở thành lười biếng (tức là trả về một máy phát điện) với python-3 trong khi trước khi nó đánh giá danh sách đầy đủ. –

+0

Vì vậy, tôi lấy nó mà tôi không bao giờ nên sử dụng phạm vi() trong máy phát điện bulding. Phạm vi sử dụng() có nghĩa là mỗi khi một giá trị máy phát mới được trả về, toàn bộ dải ô() sẽ được tạo lại? – GeorgeG

Trả lời

5

Sự cố trong mã của bạn là chức năng range. Trong Python 2, nó tạo ra một danh sách. Đối với các danh sách lớn như danh sách trong điểm chuẩn của bạn, điều này sẽ trở thành một vấn đề. Trong Python 3, range trả về một trình tạo. Cách giải quyết cho Python 2 là sử dụng hàm xrange, cũng rất lười.

Là một thử nghiệm, chúng ta hãy tạo một hàm chuẩn như của bạn, nhưng sử dụng xrange:

def returngenerator2(times): 
    t = time.time() 
    g = (i for i in xrange(times)) 
    print "generator2: {}".format(time.time() - t) 
    return g 

Và kiểm tra nó:

>>> l = returnlist(10**7) 
list: 0.580000162125 
>>> g = returngenerator(10**7) 
generator: 0.115000009537 
>>> x = returngenerator2(10**7) 
generator2: 0.0 
>>> x2 = returngenerator2(10**8) 
generator2: 0.0 
>>> x3 = returngenerator2(10**9) 
generator2: 0.0 

vẻ để làm việc. :)

0

range() trả về một danh sách thực tế trong Python 2. Trong python 3, điều này đã thay đổi để range() là một máy phát điện. Sử dụng xrange() trong Python 2 để cải thiện hiệu suất.

Các vấn đề liên quan