أين يقضي نص بيثون الوقت الخاص بي؟ هل هناك "وقت مفقود" في تتبع cprofile / pstats الخاص بي؟

StackOverflow https://stackoverflow.com/questions/2780294

سؤال

أنا أحاول أن أتعامل مع نص Python طويل المدى. يقوم البرنامج النصي ببعض التحليل المكاني على مجموعة بيانات GIS النقطية باستخدام وحدة GDAL. يستخدم البرنامج النصي حاليًا ثلاثة ملفات ، وهو البرنامج النصي الرئيسي الذي يحلق على وحدات البكسل النقطية المسمى find_pixel_pairs.py, ، ذاكرة التخزين المؤقت البسيطة في lrucache.py وبعض فصول MASC في utils.py. لقد قمت بتعيين الكود على مجموعة بيانات معتدلة الحجم. pstats عائدات:

   p.sort_stats('cumulative').print_stats(20)
   Thu May  6 19:16:50 2010    phes.profile

   355483738 function calls in 11644.421 CPU seconds

   Ordered by: cumulative time
   List reduced from 86 to 20 due to restriction <20>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.008    0.008 11644.421 11644.421 <string>:1(<module>)
        1 11064.926 11064.926 11644.413 11644.413 find_pixel_pairs.py:49(phes)
340135349  544.143    0.000  572.481    0.000 utils.py:173(extent_iterator)
  8831020   18.492    0.000   18.492    0.000 {range}
   231922    3.414    0.000    8.128    0.000 utils.py:152(get_block_in_bands)
   142739    1.303    0.000    4.173    0.000 utils.py:97(search_extent_rect)
   745181    1.936    0.000    2.500    0.000 find_pixel_pairs.py:40(is_no_data)
   285478    1.801    0.000    2.271    0.000 utils.py:98(intify)
   231922    1.198    0.000    2.013    0.000 utils.py:116(block_to_pixel_extent)
   695766    1.990    0.000    1.990    0.000 lrucache.py:42(get)
  1213166    1.265    0.000    1.265    0.000 {min}
  1031737    1.034    0.000    1.034    0.000 {isinstance}
   142740    0.563    0.000    0.909    0.000 utils.py:122(find_block_extent)
   463844    0.611    0.000    0.611    0.000 utils.py:112(block_to_pixel_coord)
   745274    0.565    0.000    0.565    0.000 {method 'append' of 'list' objects}
   285478    0.346    0.000    0.346    0.000 {max}
   285480    0.346    0.000    0.346    0.000 utils.py:109(pixel_coord_to_block_coord)
      324    0.002    0.000    0.188    0.001 utils.py:27(__init__)
      324    0.016    0.000    0.186    0.001 gdal.py:848(ReadAsArray)
        1    0.000    0.000    0.160    0.160 utils.py:50(__init__)

تحتوي المكالمتين الأعلى على الحلقة الرئيسية - التحليل بأكمله. مجموع المكالمات المتبقية إلى أقل من 625 من 11644 ثانية. أين تقضي الـ 11000 ثانية المتبقية؟ هل كل شيء داخل الحلقة الرئيسية find_pixel_pairs.py؟ إذا كان الأمر كذلك ، هل يمكنني معرفة أسطر التعليمات البرمجية التي تستغرق معظم الوقت؟

هل كانت مفيدة؟

المحلول

أنت محق في أن يقضي معظم الوقت في phes الوظيفة على الخط 49 من find_pixel_pairs.py. لمعرفة المزيد ، تحتاج إلى الانفصال phes في المزيد من الوظائف الفرعية ، ثم reprofile.

نصائح أخرى

ننسى الوظائف والقياس. استخدم هذه التقنية. ما عليك سوى تشغيله في وضع التصحيح ، وقم بـ Ctrl-C عدة مرات. سيُظهر لك مكدس المكالمات بالضبط خطوط التعليمات البرمجية المسؤولة عن الوقت.

وأضاف: على سبيل المثال ، توقف 10 مرات. إذا ، كما يقول EOL ، يتم إنفاق 10400 ثانية من أصل 11000 phes, ، ثم في حوالي 9 من هذه الإيقاف المؤقت ، سوف تتوقف هناك مباشرة. إذا ، من ناحية أخرى ، فإنها تقضي جزءًا كبيرًا من الوقت في بعض الروتين الفرعي يسمى من phes, ، لن ترى فقط مكان وجوده في تلك الروتين الفرعي ، ولكن سترى الخطوط التي تسميها ، والتي هي أيضًا مسؤولة عن الوقت ، وما إلى ذلك ، أعلى مكدس الاتصال.

لا تقيس. يأسر.

الوقت الذي يقضيه في تنفيذ الكود من كل وظيفة أو طريقة في tottime عمودي. ال cumtime الطريقة هي tottime+الوقت الذي يقضيه في وظائف تسمى.

في قائمتك ، ترى أن الـ 11000 ثانية التي تبحث عنها تقضيها مباشرة من قبل phes تعمل نفسها. ما يسميه يستغرق فقط حوالي 600 ثانية.

وبالتالي ، تريد أن تجد ما يستغرق وقتًا phes, ، عن طريق تقسيمها إلى وظائف فرعية وإعادة توصيل ، كما اقترح unutbu.

إذا حددت إمكانية الاختناقات في phes وظيفة/الطريقة في find_pixel_pairs.py, ، يمكنك استخدام line_profiler للحصول على أرقام أداء ملف تعريف تنفيذ خط واحد على حدة (تم نسخها من سؤال آخر هنا):

Timer unit: 1e-06 s

Total time: 9e-06 s
File: <ipython-input-4-dae73707787c>
Function: do_other_stuff at line 4

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
     4                                           def do_other_stuff(numbers):
     5         1            9      9.0    100.0      s = sum(numbers)

Total time: 0.000694 s
File: <ipython-input-4-dae73707787c>
Function: do_stuff at line 7

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
     7                                           def do_stuff(numbers):
     8         1           12     12.0      1.7      do_other_stuff(numbers)
     9         1          208    208.0     30.0      l = [numbers[i]/43 for i in range(len(numbers))]
    10         1          474    474.0     68.3      m = ['hello'+str(numbers[i]) for i in range(len(numbers))]

مع هذه المعلومات ، أنت تفعل ليس تحتاج إلى كسر phes حتى في وظائف فرعية متعددة ، لأنه يمكن أن ترى بدقة الخطوط التي لديها أعلى وقت للتنفيذ.

بما أنك ذكرت أن البرنامج النصي الخاص بك على المدى الطويل ، فإنني أوصي باستخدامه line_profiler في عدد محدود من الطرق قدر الإمكان ، لأنه أثناء الإضافات يضيف النفقات العامة الإضافية ، يمكن لتوصيف الخط أن يضيف المزيد.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top