2016-08-05 13 views
6

Đến từ thế giới xinh đẹp của , tôi đang cố gắng tìm hiểu hành vi này:Có phải python đủ thông minh để thay thế các cuộc gọi chức năng với kết quả không đổi?

In [1]: dataset = sqlContext.read.parquet('indir') 
In [2]: sizes = dataset.mapPartitions(lambda x: [len(list(x))]).collect() 
In [3]: for item in sizes: 
    ...:  if(item == min(sizes)): 
    ...:   count = count + 1 
    ...:   

sẽ không thậm chí kết thúc sau 20 phút, và tôi biết rằng danh sách sizes không phải là lớn, ít hơn 205k chiều dài. Tuy nhiên, điều này được thực hiện ngay lập tức:

In [8]: min_item = min(sizes) 

In [9]: for item in sizes: 
    if(item == min_item): 
     count = count + 1 
    ...:   

Vậy điều gì đã xảy ra?

tôi đoán: không thể hiểu rằng min(sizes) sẽ luôn không đổi, do đó thay thế sau vài cuộc gọi đầu tiên với sự trở lại của mình value..since Python sử dụng thông dịch viên ..


Ref của min() doesn không nói bất cứ điều gì sẽ giải thích vấn đề với tôi, nhưng những gì tôi nghĩ là nó có thể cần phải nhìn vào các phân vùng để làm điều đó, nhưng đó không phải là trường hợp, vì sizeslist , không phải là RDD!


Edit:

Đây là nguồn gốc của sự nhầm lẫn của mình, tôi đã viết một chương trình tương tự trong C:

for(i = 0; i < SIZE; ++i) 
    if(i == mymin(array, SIZE)) 
     ++count; 

và có những timings:

C02QT2UBFVH6-lm:~ gsamaras$ gcc -Wall main.c 
C02QT2UBFVH6-lm:~ gsamaras$ ./a.out 
That took 98.679177000 seconds wall clock time. 
C02QT2UBFVH6-lm:~ gsamaras$ gcc -O3 -Wall main.c 
C02QT2UBFVH6-lm:~ gsamaras$ ./a.out 
That took 0.000000000 seconds wall clock time. 

và cho timings, tôi đã sử dụng phương pháp của Nomimal Animal từ số Time measurements.

+1

Mã đầu tiên là 'O (n * n)', mã thứ hai là 'O (n)'. Điều này hỗ trợ giả thuyết như thế nào? – user2864740

+1

CPython chỉ thực sự tối ưu hóa đơn giản. Bản chất động của ngôn ngữ cũng làm cho nhiều tối ưu hóa không thể: ví dụ, hãy tưởng tượng nếu một số mã khác đã làm 'min = lambda x: 1'. –

+3

Không có ngôn ngữ không thuần túy mà tôi biết rằng thậm chí sẽ cố gắng "hiểu" tối ưu hóa này. Đối với nó thậm chí còn hợp lệ sẽ yêu cầu một đảm bảo về hành vi xác định. – user2864740

Trả lời

5

Tôi không phải là một chuyên gia về các hoạt động bên trong của trăn, nhưng từ hiểu biết của tôi vậy, đến nay bạn muốn so sánh tốc độ của

for item in sizes: 
    if(item == min(sizes)): 
     count = count + 1 

min_item = min(sizes) 
for item in sizes: 
    if(item == min_item): 
     count = count + 1 

Bây giờ ai đó sửa tôi nếu tôi có bất kỳ điều gì sai trái nhưng,

Trong danh sách trăn có thể thay đổi và không có độ dài cố định và được coi là s uch, trong khi trong C một mảng có kích thước cố định. Từ this question:

Danh sách Python rất linh hoạt và có thể chứa hoàn toàn không đồng nhất, dữ liệu tùy ý và chúng có thể được thêm vào rất hiệu quả trong thời gian cố định phân bổ. Nếu bạn cần thu nhỏ và phát triển mảng của mình một cách hiệu quả và không gặp rắc rối, chúng là cách để đi. Nhưng chúng sử dụng nhiều không gian hơn các mảng C.

Bây giờ lấy ví dụ

for item in sizes: 
    if(item == min(sizes)): 
     new_item = item - 1 
     sizes.append(new_item) 

này Sau đó, giá trị của item == min(sizes) sẽ khác nhau về phiên bản kế tiếp. Python không lưu trữ giá trị kết quả của min(sizes) vì nó sẽ phá vỡ ví dụ trên hoặc yêu cầu một số logic để kiểm tra xem danh sách đã được thay đổi chưa. Thay vào đó, nó để lại điều đó cho bạn. Bằng cách xác định min_item = min(sizes), về cơ bản bạn đang lưu vào bộ nhớ cache kết quả.

Vì mảng là kích thước cố định trong C, nó có thể tìm giá trị nhỏ nhất với ít chi phí hơn một danh sách python, do đó tôi nghĩ rằng không có vấn đề gì trong C (cũng như C thấp hơn nhiều) ngôn ngữ cấp).

Một lần nữa, tôi không hoàn toàn hiểu mã cơ bản và biên dịch cho python, và tôi chắc chắn nếu bạn phân tích quá trình của vòng trong python, bạn sẽ thấy python liên tục tính toán min(sizes), gây ra số tiền cực đại lag. Tôi muốn tìm hiểu thêm về các hoạt động bên trong của python (ví dụ, có bất kỳ phương thức nào được lưu trữ trong một vòng lặp cho python hay không, tất cả mọi thứ được tính toán lại cho mỗi lần lặp lại), vì vậy nếu có ai có thêm thông tin và/hoặc chỉnh sửa, hãy để tôi biết!

+0

Trong khi bạn có một điểm và tôi chấp nhận câu trả lời của bạn, được cảnh báo rằng tôi không nghĩ rằng nó là 100% rõ ràng. Ví dụ tôi chỉ làm cùng một suy nghĩ với một 'std :: vector' và có 115,9 giây. và 8,4 giây, cho thấy sự tăng tốc đáng kể, bất chấp sự linh hoạt của vectơ. Vì vậy, tôi sẽ nói rằng nó là một điều [tag: python], chứ không phải là sự linh hoạt của cấu trúc dữ liệu .. – gsamaras

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