ÕýÎÄ
×¢Ò⣺±¾Îijý·ÇÌØÊâÖ¸Ã÷£¬¡±python¡°¶¼ÊÇ´ú±íCPython£¬¼´CÓïÑÔʵÏֵıê×¼python£¬ÇÒ±¾ÎÄËùÌÖÂÛµÄÊǰ汾Ϊ2.7µÄCPython¡£
pythonΪʲôÐÔÄܲ
µ±ÎÒÃÇÌáµ½Ò»Ãűà³ÌÓïÑÔµÄЧÂÊʱ£ºÍ¨³£ÓÐÁ½²ãÒâ˼£¬µÚÒ»ÊÇ¿ª·¢Ð§ÂÊ£¬ÕâÊǶԳÌÐòÔ±¶øÑÔ£¬Íê³É±àÂëËùÐèÒªµÄʱ¼ä;ÁíÒ»¸öÊÇÔËÐÐЧÂÊ£¬ÕâÊǶԼÆËã»ú¶øÑÔ£¬Íê³É¼ÆËãÈÎÎñËùÐèÒªµÄʱ¼ä¡£±àÂëЧÂʺÍÔËÐÐЧÂÊÍùÍùÊÇÓãÓëÐÜÕÆµÄ¹ØÏµ£¬ÊǺÜÄÑͬʱ¼æ¹ËµÄ¡£²»Í¬µÄÓïÑÔ»áÓв»Í¬µÄ²àÖØ£¬pythonÓïÑÔºÁÎÞÒÉÎʸüÔÚºõ±àÂëЧÂÊ£¬life
is short£¬we use python¡£
ËäȻʹÓÃpythonµÄ±à³ÌÈËÔ±¶¼Ó¦¸Ã½ÓÊÜÆäÔËÐÐЧÂʵ͵ÄÊÂʵ£¬µ«pythonÔÚÔ½¶àÔ½À´µÄÁìÓò¶¼Óй㷺ӦÓ㬱ÈÈç¿ÆÑ§¼ÆËã
¡¢web·þÎñÆ÷µÈ¡£³ÌÐòÔ±µ±È»Ò²Ï£ÍûpythonÄܹ»ÔËËãµÃ¸ü¿ì£¬Ï£Íûpython¿ÉÒÔ¸üÇ¿´ó¡£
Ê×ÏÈ£¬pythonÏà±ÈÆäËûÓïÑÔ¾ßÌåÓжàÂý£¬Õâ¸ö²»Í¬³¡¾°ºÍ²âÊÔÓÃÀý£¬½á¹û¿Ï¶¨ÊDz»Ò»ÑùµÄ¡£Õâ¸öÍøÖ·¸ø³öÁ˲»Í¬ÓïÑÔÔÚ¸÷ÖÖcaseϵÄÐÔÄܶԱȣ¬ÕâÒ»Ò³ÊÇpython3ºÍC++µÄ¶Ô±È£¬ÏÂÃæÊÇÁ½¸öcase£º

pythonÔËËãЧÂʵͣ¬¾ßÌåÊÇʲôÔÒòÄØ£¬ÏÂÁÐÂÞÁÐһЩ
µÚÒ»£ºpythonÊǶ¯Ì¬ÓïÑÔ
Ò»¸ö±äÁ¿ËùÖ¸Ïò¶ÔÏóµÄÀàÐÍÔÚÔËÐÐʱ²ÅÈ·¶¨£¬±àÒëÆ÷×ö²»ÁËÈκÎÔ¤²â£¬Ò²¾ÍÎÞ´ÓÓÅ»¯¡£¾ÙÒ»¸ö¼òµ¥µÄÀý×Ó£º¡¡r
= a + b¡£¡¡aºÍbÏà¼Ó£¬µ«aºÍbµÄÀàÐÍÔÚÔËÐÐʱ²ÅÖªµÀ£¬¶ÔÓÚ¼Ó·¨²Ù×÷£¬²»Í¬µÄÀàÐÍÓв»Í¬µÄ´¦Àí£¬ËùÒÔÿ´ÎÔËÐеÄʱºò¶¼»áÈ¥ÅжÏaºÍbµÄÀàÐÍ£¬È»ºóÖ´ÐжÔÓ¦µÄ²Ù×÷¡£¶øÔÚ¾²Ì¬ÓïÑÔÈçC++ÖУ¬±àÒëµÄʱºò¾ÍÈ·¶¨ÁËÔËÐÐʱµÄ´úÂë¡£
ÁíÍâÒ»¸öÀý×ÓÊÇÊôÐÔ²éÕÒ£¬¹ØÓÚ¾ßÌåµÄ²éÕÒ˳ÐòÔÚ¡¶pythonÊôÐÔ²éÕÒ¡·ÖÐÓÐÏêϸ½éÉÜ¡£¼ò¶øÑÔÖ®£¬·ÃÎʶÔÏóµÄij¸öÊôÐÔÊÇÒ»¸ö·Ç³£¸´ÔӵĹý³Ì£¬¶øÇÒͨ¹ýͬһ¸ö±äÁ¿·ÃÎʵ½µÄpython¶ÔÏó»¹¶¼¿ÉÄܲ»Ò»Ñù(²Î¼ûLazy
propertyµÄÀý×Ó)¡£¶øÔÚCÓïÑÔÖУ¬·ÃÎÊÊôÐÔÓöÔÏóµÄµØÖ·¼ÓÉÏÊôÐÔµÄÆ«ÒƾͿÉÒÔÁË¡£
µÚ¶þ£ºpythonÊǽâÊÍÖ´ÐУ¬µ«ÊDz»Ö§³ÖJIT(just in time compiler)¡£ËäÈ»´óÃû¶¦¶¦µÄgoogleÔø¾³¢ÊÔUnladen
Swallow Õâ¸öÏîÄ¿£¬µ«×îÖÕÒ²ÕÛÁË¡£
µÚÈý£ºpythonÖÐÒ»Çж¼ÊǶÔÏó£¬Ã¿¸ö¶ÔÏó¶¼ÐèҪά»¤ÒýÓüÆÊý£¬Ôö¼ÓÁ˶îÍâµÄ¹¤×÷¡£
µÚËÄ£ºpython GIL
GILÊÇPython×îΪڸ²¡µÄÒ»µã£¬ÒòΪGIL£¬pythonÖеĶàÏ̲߳¢²»ÄÜÕæÕýµÄ²¢·¢¡£Èç¹ûÊÇÔÚIO
boundµÄÒµÎñ³¡¾°£¬Õâ¸öÎÊÌâ²¢²»´ó£¬µ«ÊÇÔÚCPU BOUNDµÄ³¡¾°£¬Õâ¾ÍºÜÖÂÃüÁË¡£ËùÒÔ±ÊÕßÔÚ¹¤×÷ÖÐʹÓÃpython¶àÏ̵߳ÄÇé¿ö²¢²»¶à£¬Ò»°ã¶¼ÊÇʹÓÃ¶à½ø³Ì(pre
fork)£¬»òÕßÔÚ¼ÓÉÏг̡£¼´Ê¹ÔÚµ¥Ị̈߳¬GILÒ²»á´øÀ´ºÜ´óµÄÐÔÄÜÓ°Ï죬ÒòΪpythonÿִÐÐ100¸öopcode(ĬÈÏ£¬¿ÉÒÔͨ¹ýsys.setcheckinterval()ÉèÖÃ)¾Í»á³¢ÊÔÏ̵߳ÄÇл»£¬¾ßÌåµÄÔ´´úÂëÔÚceval.c::PyEval_EvalFrameEx¡£
µÚÎ壺À¬»ø»ØÊÕ£¬Õâ¸ö¿ÉÄÜÊÇËùÓоßÓÐÀ¬»ø»ØÊյıà³ÌÓïÑÔµÄͨ²¡¡£
python²ÉÓñê¼ÇºÍ·Ö´úµÄÀ¬»ø»ØÊÕ²ßÂÔ£¬Ã¿´ÎÀ¬»ø»ØÊÕµÄʱºò¶¼»áÖжÏÕýÔÚÖ´ÐеijÌÐò£¬Ôì³ÉËùνµÄ¶Ù¿¨¡£infoqÉÏÓÐһƪÎÄÕ£¬Ìáµ½½ûÓÃPythonµÄGC»úÖÆºó£¬InstagramÐÔÄÜÌáÉýÁË10%¡£¸ÐÐËȤµÄ¶ÁÕß¿ÉÒÔȥϸ¶Á¡£
Be pythonic
ÎÒÃǶ¼ÖªµÀ ¹ýÔçµÄÓÅ»¯ÊÇ×ï¶ñÖ®Ô´£¬Ò»ÇÐÓÅ»¯¶¼ÐèÒª»ùÓÚprofile¡£µ«ÊÇ£¬×÷Ϊһ¸öpython¿ª·¢ÕßÓ¦¸ÃÒªpythonic£¬¶øÇÒpythonicµÄ´úÂëÍùÍù±Ènon-pythonicµÄ´úÂëЧÂʸßһЩ£¬±ÈÈ磺
ʹÓõü´úÆ÷iterator£¬for example£º
dictµÄiteritems ¶ø²»ÊÇitems(ͬitervalues£¬iterkeys)
ʹÓÃgenerator£¬ÌرðÊÇÔÚÑ»·ÖпÉÄÜÌáǰbreakµÄÇé¿ö
ÅжÏÊÇ·ñÊÇͬһ¸ö¶ÔÏóʹÓà is ¶ø²»ÊÇ ==
ÅжÏÒ»¸ö¶ÔÏóÊÇ·ñÔÚÒ»¸ö¼¯ºÏÖУ¬Ê¹ÓÃset¶ø²»ÊÇlist
ÀûÓöÌ·ÇóÖµÌØÐÔ£¬°Ñ¡°¶Ì·¡±¸ÅÂʹýµÄÂß¼±í´ïʽдÔÚÇ°Ãæ¡£ÆäËûµÄlazy ideasÒ²ÊÇ¿ÉÒÔµÄ
¶ÔÓÚ´óÁ¿×Ö·û´®µÄÀÛ¼Ó£¬Ê¹ÓÃjoin²Ù×÷
ʹÓÃfor else(while else)Óï·¨
½»»»Á½¸ö±äÁ¿µÄֵʹÓ㺠a, b = b, a
»ùÓÚprofileµÄÓÅ»¯
¼´Ê¹ÎÒÃǵĴúÂëÒѾ·Ç³£pythonicÁË£¬µ«¿ÉÄÜÔËÐÐЧÂÊ»¹ÊDz»ÄÜÂú×ãÔ¤ÆÚ¡£ÎÒÃÇÒ²ÖªµÀ80/20¶¨ÂÉ£¬¾ø´ó¶àÊýµÄʱ¼ä¶¼ºÄ·ÑÔÚÉÙÁ¿µÄ´úÂëÆ¬¶ÎÀïÃæÁË£¬ÓÅ»¯µÄ¹Ø¼üÔÚÓÚÕÒ³öÕâЩƿ¾±´úÂë¡£·½Ê½ºÜ¶à£ºµ½´¦¼Ólog´òӡʱ¼ä´Á¡¢»òÕß½«»³Òɵĺ¯ÊýʹÓÃtimeit½øÐе¥¶À²âÊÔ£¬µ«×îÓÐЧµÄÊÇʹÓÃprofile¹¤¾ß¡£
python profilers
¶ÔÓÚpython³ÌÐò£¬±È½Ï³öÃûµÄprofile¹¤¾ßÓÐÈý¸ö£ºprofile¡¢cprofileºÍhotshot¡£ÆäÖÐprofileÊÇ´¿pythonÓïÑÔʵÏֵģ¬Cprofile½«profileµÄ²¿·ÖʵÏÖnative»¯£¬hotshotÒ²ÊÇCÓïÑÔʵÏÖ£¬hotshotÓëCprofileµÄÇø±ðÔÚÓÚ£ºhotshot¶ÔÄ¿±ê´úÂëµÄÔËÐÐÓ°Ïì½ÏС£¬´ú¼ÛÊǸü¶àµÄºó´¦Àíʱ¼ä£¬¶øÇÒhotshotÒѾֹͣά»¤ÁË¡£ÐèҪעÒâµÄÊÇ£¬profile(Cprofile
hotshot)Ö»Êʺϵ¥Ï̵߳Äpython³ÌÐò¡£
¶ÔÓÚ¶àỊ̈߳¬¿ÉÒÔʹÓÃyappi£¬yappi²»½öÖ§³Ö¶àỊ̈߳¬»¹¿ÉÒÔ¾«È·µ½CPUʱ¼ä
¶ÔÓÚгÌ(greenlet)£¬¿ÉÒÔʹÓÃgreenletprofiler£¬»ùÓÚyappiÐ޸ģ¬ÓÃgreenlet
context hookסthread context
ÏÂÃæ¸ø³öÒ»¶Î±àÔìµÄ¡±Ð§ÂʵÍÏ¡°µÄ´úÂ룬²¢Ê¹ÓÃCprofileÀ´ËµÃ÷profileµÄ¾ßÌå·½·¨ÒÔ¼°ÎÒÃÇ¿ÉÄÜÓöµ½µÄÐÔÄÜÆ¿¾±¡£
# -*- coding:
UTF-8 -*-
from cProfile import Profile
import math
def foo():
return foo1()
def foo1():
return foo2()
def foo2():
return foo3()
def foo3():
return foo4()
def foo4():
return "this call tree seems ugly, but it
always happen"
def bar():
ret = 0
for i in xrange(10000):
ret += i * i + math.sqrt(i)
return ret
def main():
for i in range(100000):
if i % 10000 == 0:
bar()
else:
foo()
if __name__ == '__main__':
prof = Profile()
prof.runcall(main)
prof.print_stats()
#prof.dump_stats('test.prof') # dump profile result
to test.prof
code for profile |
ÔËÐнá¹ûÈçÏ£º

¶ÔÓÚÉÏÃæµÄµÄÊä³ö£¬Ã¿Ò»¸ö×Ö¶ÎÒâÒåÈçÏ£º
ncalls º¯Êý×ܵĵ÷ÓôÎÊý
tottime º¯ÊýÄÚ²¿(²»°üÀ¨×Óº¯Êý)µÄÕ¼ÓÃʱ¼ä
percall(µÚÒ»¸ö) tottime/ncalls
cumtime º¯Êý°üÀ¨×Óº¯ÊýËùÕ¼ÓõÄʱ¼ä
percall(µÚ¶þ¸ö)cumtime/ncalls
filename:lineno(function) Îļþ£ºÐкÅ(º¯Êý)
´úÂëÖеÄÊä³ö·Ç³£¼òµ¥£¬ÊÂʵÉÏ¿ÉÒÔÀûÓÃpstat£¬ÈÃprofile½á¹ûµÄÊä³ö¶àÑù»¯£¬¾ßÌå¿ÉÒԲμû¹Ù·½Îĵµpython
profiler¡£
profile GUI tools
ËäÈ»CprofileµÄÊä³öÒѾ±È½ÏÖ±¹Û£¬µ«ÎÒÃÇ»¹ÊÇÇãÏòÓÚ±£´æprofileµÄ½á¹û£¬È»ºóÓÃͼÐλ¯µÄ¹¤¾ßÀ´´Ó²»Í¬µÄά¶ÈÀ´·ÖÎö£¬»òÕ߱ȽÏÓÅ»¯Ç°ºóµÄ´úÂë¡£²é¿´profile½á¹ûµÄ¹¤¾ßÒ²±È½Ï¶à£¬±ÈÈ磬visualpytune¡¢qcachegrind¡¢runsnakerun£¬±¾ÎÄÓÃvisualpytune×ö·ÖÎö¡£¶ÔÓÚÉÏÃæµÄ´úÂ룬°´ÕÕ×¢ÊÍÉú³ÉÐ޸ĺóÖØÐÂÔËÐÐÉú³Étest.profÎļþ£¬ÓÃvisualpytuneÖ±½Ó´ò¿ª¾Í¿ÉÒÔÁË£¬ÈçÏ£º

×ֶεÄÒâÒåÓëÎı¾Êä³ö»ù±¾Ò»Ö£¬²»¹ý±ã½ÝÐÔ¿ÉÒÔµã»÷×Ö¶ÎÃûÅÅÐò¡£×óÏ·½ÁгöÁ˵±Ç°º¯ÊýµÄcalller(µ÷ÓÃÕß)£¬ÓÒÏ·½Êǵ±Ç°º¯ÊýÄÚ²¿Óë×Óº¯ÊýµÄʱ¼äÕ¼ÓÃÇé¿ö¡£ÉÏÈçÊǰ´ÕÕcumtime(¼´¸Ãº¯ÊýÄÚ²¿¼°Æä×Óº¯ÊýËùÕ¼µÄʱ¼äºÍ)ÅÅÐòµÄ½á¹û¡£
Ôì³ÉÐÔÄÜÆ¿¾±µÄÔÒòͨ³£ÊÇ¸ßÆµµ÷Óõĺ¯Êý¡¢µ¥´ÎÏûºÄ·Ç³£¸ßµÄº¯Êý¡¢»òÕß¶þÕߵĽáºÏ¡£ÔÚÎÒÃÇÇ°ÃæµÄÀý×ÓÖУ¬foo¾ÍÊôÓÚ¸ßÆµµ÷ÓõÄÇé¿ö£¬barÊôÓÚµ¥´ÎÏûºÄ·Ç³£¸ßµÄÇé¿ö£¬Õâ¶¼ÊÇÎÒÃÇÐèÒªÓÅ»¯µÄÖØµã¡£
python-profiling-toolsÖнéÉÜÁËqcachegrindºÍrunsnakerunµÄʹÓ÷½·¨£¬ÕâÁ½¸öcolorfulµÄ¹¤¾ß±ÈvisualpytuneÇ¿´óµÃ¶à¡£¾ßÌåµÄʹÓ÷½·¨Çë²Î¿¼ÔÎÄ£¬ÏÂͼ¸ø³ötest.profÓÃqcachegrind´ò¿ªµÄ½á¹û¡£
 qcachegrindȷʵҪ±ÈvisualpytuneÇ¿´ó¡£´ÓÉÏͼ¿ÉÒÔ¿´µ½£¬´óÖ·ÖΪÈý²¿£º¡£µÚÒ»²¿·ÖͬvisualpytuneÀàËÆ£¬ÊÇÿ¸öº¯ÊýÕ¼ÓõÄʱ¼ä£¬ÆäÖÐInclµÈͬÓÚcumtime£¬
SelfµÈͬÓÚtottime¡£µÚ¶þ²¿·ÖºÍµÚÈý²¿·Ö¶¼Óкܶà±êÇ©£¬²»Í¬µÄ±êÇ©±êʾ´Ó²»Í¬µÄ½Ç¶ÈÀ´¿´½á¹û£¬ÈçͼÉÏËùÒÔ£¬µÚÈý²¿·ÖµÄ¡°call
graph¡±Õ¹Ê¾Á˸ú¯ÊýµÄcall tree²¢°üº¬Ã¿¸ö×Óº¯ÊýµÄʱ¼ä°Ù·Ö±È£¬Ò»Ä¿ÁËÈ»¡£
profileÕë¶ÔÓÅ»¯
ÖªµÀÁËÈȵ㣬¾Í¿ÉÒÔ½øÐÐÕë¶ÔÐÔµÄÓÅ»¯£¬¶øÕâ¸öÓÅ»¯ÍùÍù¸ù¾ßÌåµÄÒµÎñÃÜÇÐÏà¹Ø£¬Ã»ÓÃÍòÄÜÔ¿³×£¬¾ßÌåÎÊÌ⣬¾ßÌå·ÖÎö¡£¸öÈ˾Ñé¶øÑÔ£¬×îÓÐЧµÄÓÅ»¯ÊÇÕÒ²úÆ·¾ÀíÌÖÂÛÐèÇ󣬿ÉÄÜ»»Ò»ÖÖ·½Ê½Ò²ÄÜÂú×ãÐèÇó£¬ÉÙÕßÉÔ΢ÕÛÖÔһϲúÆ·¾ÀíÒ²ÄܽÓÊÜ¡£´ÎÖ®ÊÇÐ޸ĴúÂëµÄʵÏÖ£¬±ÈÈç֮ǰʹÓÃÁËÒ»¸ö±È½ÏͨË×Ò×¶®µ«Ð§Âʽϵ͵ÄËã·¨£¬Èç¹ûÕâ¸öËã·¨³ÉΪÁËÐÔÄÜÆ¿¾±£¬ÄǾͿ¼ÂÇ»»Ò»ÖÖЧÂʸü¸ßµ«ÊÇ¿ÉÄÜÄÑÀí½âµÄËã·¨¡¢»òÕßʹÓÃdirty
Flagģʽ¡£¶ÔÓÚÕâЩͬÑùµÄ·½·¨£¬ÐèÒª½áºÏ¾ßÌåµÄ°¸Àý£¬±¾ÎIJ»×ö׸Êö¡£
½ÓÏÂÀ´½áºÏpythonÓïÑÔÌØÐÔ£¬½éÉÜһЩÈÃpython´úÂë²»ÄÇôpythonic£¬µ«¿ÉÒÔÌáÉýÐÔÄܵÄһЩ×ö·¨
µÚÒ»£º¼õÉÙº¯ÊýµÄµ÷Óòã´Î
ÿһ²ãº¯Êýµ÷Óö¼»á´øÀ´²»Ð¡µÄ¿ªÏú£¬Ìرð¶ÔÓÚµ÷ÓÃÆµÂʸߣ¬µ«µ¥´ÎÏûºÄ½ÏСµÄcalltree£¬¶à²ãµÄº¯Êýµ÷ÓÿªÏú¾ÍºÜ´ó£¬Õâ¸öʱºò¿ÉÒÔ¿¼Âǽ«ÆäÕ¹¿ª¡£
¶ÔÓÚ֮ǰµ÷µ½µÄprofileµÄ´úÂ룬fooÕâ¸öcall tree·Ç³£¼òµ¥£¬µ«ÆµÂʸߡ£Ð޸ĴúÂ룬Ôö¼ÓÒ»¸öplain_foo()º¯Êý,
Ö±½Ó·µ»Ø×îÖÕ½á¹û£¬¹Ø¼üÊä³öÈçÏ£º

¸ú֮ǰµÄ½á¹û¶Ô±È£º

¿ÉÒÔ¿´µ½£¬ÓÅ»¯Á˲¶à3±¶¡£
µÚ¶þ£ºÓÅ»¯ÊôÐÔ²éÕÒ
ÉÏÃæÌáµ½£¬python µÄÊôÐÔ²éÕÒЧÂʺܵͣ¬Èç¹ûÔÚÒ»¶Î´úÂëÖÐÆµ·±·ÃÎÊÒ»¸öÊôÐÔ(±ÈÈçforÑ»·)£¬ÄÇô¿ÉÒÔ¿¼ÂÇÓþֲ¿±äÁ¿´úÌæ¶ÔÏóµÄÊôÐÔ¡£
µÚÈý£º¹Ø±ÕGC
ÔÚ±¾ÎĵĵÚÒ»Õ½ÚÒѾÌáµ½£¬¹Ø±ÕGC¿ÉÒÔÌáÉýpythonµÄÐÔÄÜ£¬GC´øÀ´µÄ¶Ù¿¨ÔÚʵʱÐÔÒªÇó±È½Ï¸ßµÄÓ¦Óó¡¾°Ò²ÊÇÄÑÒÔ½ÓÊܵġ£µ«¹Ø±ÕGC²¢²»ÊÇÒ»¼þÈÝÒ×µÄÊÂÇé¡£ÎÒÃÇÖªµÀpythonµÄÒýÓüÆÊýÖ»ÄÜÓ¦¸¶Ã»ÓÐÑ»·ÒýÓõÄÇé¿ö£¬ÓÐÁËÑ»·ÒýÓþÍÐèÒª¿¿GCÀ´´¦Àí¡£ÔÚpythonÓïÑÔÖÐ,
д³öÑ»·ÒýÓ÷dz£ÈÝÒס£±ÈÈ磺
case 1£º
a, b = SomeClass(), SomeClass()
a.b, b.a = b, a
¡¡
case 2£º
lst = []
lst.append(lst)
case 3£º
self.handler = self.some_func |
µ±È»£¬´ó¼Ò¿ÉÄÜ˵£¬Ë»áÕâôɵ£¬Ð´³öÕâÑùµÄ´úÂ룬Êǵģ¬ÉÏÃæµÄ´úÂëÌ«Ã÷ÏÔ£¬µ±Öмä¶à¼¸¸ö²ã¼¶Ö®ºó£¬¾Í»á³öÏÖ¡°¼ä½Ó¡±µÄÑ»·Ó¦Óá£ÔÚpythonµÄ±ê×¼¿â
collectionsÀïÃæµÄOrderedDict¾ÍÊÇcase2£º

Òª½â¾öÑ»·ÒýÓ㬵ÚÒ»¸ö°ì·¨ÊÇʹÓÃÈõÒýÓÃ(weakref)£¬µÚ¶þ¸öÊÇÊÖ¶¯½âÑ»·ÒýÓá£
µÚËÄ£ºsetcheckinterval
Èç¹û³ÌÐòÈ·¶¨Êǵ¥Ị̈߳¬ÄÇôÐÞ¸ÄcheckintervalΪһ¸ö¸ü´óµÄÖµ£¬ÕâÀïÓнéÉÜ¡£
µÚÎ壺ʹÓÃ__slots__
slots×îÖ÷ÒªµÄÄ¿µÄÊÇÓÃÀ´½ÚÊ¡Äڴ棬µ«ÊÇÒ²ÄÜÒ»¶¨³Ì¶ÈÉÏÌá¸ßÐÔÄÜ¡£ÎÒÃÇÖªµÀ¶¨ÒåÁË__slots__µÄÀ࣬¶Ôijһ¸öʵÀý¶¼»áÔ¤Áô×ã¹»µÄ¿Õ¼ä£¬Ò²¾Í²»»áÔÙ×Ô¶¯´´½¨__dict__¡£µ±È»£¬Ê¹ÓÃ__slots__Ò²ÓÐÐí¶à×¢ÒâÊÂÏ×îÖØÒªµÄÒ»µã£¬¼Ì³ÐÁ´ÉϵÄËùÓÐÀà¶¼±ØÐ붨Òå__slots__£¬python
docÓÐÏêϸµÄÃèÊö¡£ÏÂÃæ¿´Ò»¸ö¼òµ¥µÄ²âÊÔÀý×Ó£º
class BaseSlots(object):
__slots__ = ['e', 'f', 'g']
class Slots(BaseSlots):
__slots__ = ['a', 'b', 'c', 'd']
def __init__(self):
self.a = self.b = self.c = self.d = self.e = self.f
= self.g = 0
class BaseNoSlots(object):
pass
class NoSlots(BaseNoSlots):
def __init__(self):
super(NoSlots,self).__init__()
self.a = self.b = self.c = self.d = self.e = self.f
= self.g = 0
def log_time(s):
begin = time.time()
for i in xrange(10000000):
s.a,s.b,s.c,s.d, s.e, s.f, s.g
return time.time() - begin
if __name__ == '__main__':
print 'Slots cost', log_time(Slots())
print 'NoSlots cost', log_time(NoSlots()) |
Êä³ö½á¹û£º
Slots cost 3.12999987602
NoSlots cost 3.48100018501 |
python CÀ©Õ¹
Ò²Ðíͨ¹ýprofile£¬ÎÒÃÇÒѾÕÒµ½ÁËÐÔÄÜÈȵ㣬µ«Õâ¸öÈȵã¾ÍÊÇÒªÔËÐдóÁ¿µÄ¼ÆË㣬¶øÇÒû·¨cache£¬Ã»·¨Ê¡ÂÔ¡£¡£¡£Õâ¸öʱºò¾Í¸ÃpythonµÄCÀ©Õ¹³öÂíÁË£¬CÀ©Õ¹¾ÍÊǰѲ¿·Öpython´úÂëÓÃC»òÕßC++ÖØÐÂʵÏÖ£¬È»ºó±àÒë³É¶¯Ì¬Á´½Ó¿â£¬Ìṩ½Ó¿Ú¸øÆäËüpython´úÂëµ÷Óá£ÓÉÓÚCÓïÑÔµÄЧÂÊÔ¶Ô¶¸ßÓÚpython´úÂ룬ËùÒÔʹÓÃCÀ©Õ¹ÊǷdz£ÆÕ±éµÄ×ö·¨£¬±ÈÈçÎÒÃÇÇ°ÃæÌáµ½µÄcProfile¾ÍÊÇ»ùÓÚ_lsprof.soµÄÒ»²ã·â×°¡£pythonµÄ´óËùÊô¶ÔÐÔÄÜÓÐÒªÇóµÄ¿â¶¼Ê¹ÓûòÕßÌṩÁËCÀ©Õ¹£¬Èçgevent¡¢protobuff¡¢bson¡£
±ÊÕßÔø¾²âÊÔ¹ý´¿python°æ±¾µÄbsonºÍcbsonµÄЧÂÊ£¬ÔÚ×ۺϵÄÇé¿öÏ£¬cbson¿ìÁ˲¶à10±¶!
pythonµÄCÀ©Õ¹Ò²ÊÇÒ»¸ö·Ç³£¸´ÔÓµÄÎÊÌ⣬±¾ÎĽö¸ø³öһЩעÒâÊÂÏ
µÚÒ»£º×¢ÒâÒýÓüÆÊýµÄÕýÈ·¹ÜÀí
ÕâÊÇ×îÄÑ×ÔÓµÄÒ»µã¡£ÎÒÃǶ¼ÖªµÀpython»ùÓÚÖ¸Õë¼¼ÊõÀ´¹ÜÀí¶ÔÏóµÄÉúÃüÖÜÆÚ£¬Èç¹ûÔÚÀ©Õ¹ÖÐÒýÓüÆÊý³öÁËÎÊÌ⣬ÄÇôҪôÊdzÌÐò±ÀÀ££¬ÒªÃ´ÊÇÄÚ´æÐ¹Â©¡£¸üÒªÃüµÄÊÇ£¬ÒýÓüÆÊýµ¼ÖµÄÎÊÌâºÜÄÑdebug¡£¡£¡£
CÀ©Õ¹ÖйØÓÚÒýÓüÆÊý×î¹Ø¼üµÄÈý¸ö´ÊÊÇ£ºsteal reference£¬borrowed reference£¬new
reference¡£½¨Òé±àдÀ©Õ¹´úÂë֮ǰϸ¶ÁpythonµÄ¹Ù·½Îĵµ¡£
µÚ¶þ£ºCÀ©Õ¹Óë¶àÏß³Ì
ÕâÀïµÄ¶àÏß³ÌÊÇÖ¸ÔÚÀ©Õ¹ÖÐnew³öÀ´µÄCÓïÑÔỊ̈߳¬¶ø²»ÊÇpythonµÄ¶àỊ̈߳¬³öÁËpython docÀïÃæµÄ½éÉÜ£¬Ò²¿ÉÒÔ¿´¿´¡¶python
cookbook¡·µÄÏà¹ØÕ½ڡ£
µÚÈý£ºCÀ©Õ¹Ó¦Óó¡¾°
½öÊʺÏÓëÒµÎñ´úÂëµÄ¹ØÏµ²»ÄÇô½ôÃܵÄÂß¼£¬Èç¹ûÒ»¶Î´úÂë´óÁ¿ÒµÎñÏà¹ØµÄ¶ÔÏó ÊôÐԵϰ£¬ÊǺÜÄÑCÀ©Õ¹µÄ
½«CÀ©Õ¹·â×°³Épython´úÂë¿Éµ÷ÓõĽӿڵĹý³Ì³ÆÖ®Îªbinding£¬Cpython±¾Éí¾ÍÌṩÁËÒ»Ì×ÔÉúµÄAPI£¬ËäȻʹÓÃ×îΪ¹ã·º£¬µ«¸Ã¹æ·¶±È½Ï¸´ÔÓ¡£ºÜ¶àµÚÈý·½¿â×öÁ˲»Í¬³Ì¶ÈµÄ·â×°£¬ÒԱ㿪·¢ÕßʹÓ㬱ÈÈçboost.python¡¢cython¡¢ctypes¡¢cffi(ͬʱ֧³Öpypy
cpython)£¬¾ßÌåÔõôʹÓÿÉÒÔgoogle¡£
beyond CPython
¾¡¹ÜpythonµÄÐÔÄܲîÇ¿ÈËÒ⣬µ«ÊÇÆäÒ×ѧÒ×ÓõÄÌØÐÔ»¹ÊÇÓ®µÃÔ½À´Ô½¶àµÄʹÓÃÕߣ¬Òµ½ç´óÅ£Ò²´ÓÀ´Ã»ÓÐ·ÅÆú¶ÔpythonµÄÓÅ»¯¡£ÕâÀïµÄÓÅ»¯ÊǶÔpythonÓïÑÔÉè¼ÆÉÏ¡¢»òÕßʵÏÖÉϵÄһЩ·´Ë¼»òÕßÔöÇ¿¡£ÕâЩÓÅ»¯ÏîĿһЩÒѾزÕÛ£¬Ò»Ð©»¹ÔÚ½øÒ»²½¸ÄÉÆÖУ¬ÔÚÕâ¸öÕ½ڽéÉÜĿǰ»¹²»´íµÄһЩÏîÄ¿¡£
cython
Ç°ÃæÌáµ½cython¿ÉÒÔÓõ½binding cÀ©Õ¹£¬µ«ÊÇÆä×÷ÓÃÔ¶Ô¶²»Ö¹ÕâÒ»µã¡£
CythonµÄÖ÷ҪĿµÄÊǼÓËÙpythonµÄÔËÐÐЧÂÊ£¬µ«ÊÇÓÖ²»ÏñÉÏÒ»Õ½ÚÌáµ½µÄCÀ©Õ¹ÄÇô¸´ÔÓ¡£ÔÚCythonÖУ¬Ð´CÀ©Õ¹ºÍдpython´úÂëµÄ¸´ÔӶȲ¶à(¶à¿÷ÁËPyrex)¡£CythonÊÇpythonÓïÑԵij¬¼¯£¬Ôö¼ÓÁ˶ÔCÓïÑÔº¯Êýµ÷ÓúÍÀàÐÍÉùÃ÷µÄÖ§³Ö¡£´ÓÕâ¸ö½Ç¶ÈÀ´¿´£¬cython½«¶¯Ì¬µÄpython´úÂëת»»³É¾²Ì¬±àÒëµÄC´úÂ룬ÕâÒ²ÊÇcython¸ßЧµÄÔÒò¡£Ê¹ÓÃcythonͬCÀ©Õ¹Ò»Ñù£¬ÐèÒª±àÒë³É¶¯Ì¬Á´½Ó¿â£¬ÔÚlinux»·¾³Ï¼ȿÉÒÔÓÃÃüÁîÐУ¬Ò²¿ÉÒÔÓÃdistutils¡£
Èç¹ûÏëҪϵͳѧϰcython£¬½¨Òé´Ócython documentÈëÊÖ£¬ÎĵµÐ´µÃºÜºÃ¡£ÏÂÃæÍ¨¹ýÒ»¸ö¼òµ¥µÄʾÀýÀ´Õ¹Ê¾cythonµÄʹÓ÷½·¨ºÍÐÔÄÜ(linux»·¾³)¡£
Ê×ÏÈ£¬°²×°cython£º
ÏÂÃæÊDzâÊÔÓõÄpython´úÂ룬¿ÉÒÔ¿´µ½ÕâÁ½¸öcase¶¼ÊÇÔËË㸴ÔӶȱȽϸߵÄÀý×Ó£º
def f():
return x**2-x
def integrate_f(a, b, N):
s = 0
dx = (b-a)/N
for i in range(N):
s += f(a+i*dx)
return s * dx
def main():
import time
begin = time.time()
for i in xrange(10000):
for i in xrange(100):f(10)
print 'call f cost:', time.time() - begin
begin = time.time()
for i in xrange(10000):
integrate_f(1.0, 100.0, 1000)
print 'call integrate_f cost:', time.time() -
begin
if __name__ == '__main__':
main() |
ÔËÐнá¹û£º
call f cost: 0.215116024017
call integrate_f cost: 4.33698010445 |
²»¸Ä¶¯ÈκÎpython´úÂëÒ²¿ÉÒÔÏíÊܵ½cython´øÀ´µÄÐÔÄÜÌáÉý£¬¾ßÌå×ö·¨ÈçÏ£º
step1£º½«ÎļþÃû(cython_example.py)¸ÄΪcython_example.pyx
step2£ºÔö¼ÓÒ»¸ösetup.pyÎļþ£¬Ìí¼ÓһϴúÂ룺
from distutils.core
import setup
from Cython.Build import cythonize
setup(
name = 'cython_example',
ext_modules = cythonize("cython_example.pyx"),
) |
step3£ºÖ´ÐÐpython setup.py build_ext ¨Cinplace

¿ÉÒÔ¿´µ½ Ôö¼ÓÁËÁ½¸öÎļþ£¬¶ÔÓ¦Öмä½á¹ûºÍ×îºóµÄ¶¯Ì¬Á´½Ó¿â
step4£ºÖ´ÐÐÃüÁî python -c ¡°import cython_example;cython_example.main()¡±(×¢Ò⣺
±£Ö¤µ±Ç°»·¾³ÏÂÒѾûÓÐ cython_example.py)
ÔËÐнá¹û£º
call f cost:
0.0874309539795
call integrate_f cost: 2.92381191254 |
ÐÔÄÜÌáÉýÁË´ó¸ÅÁ½±¶£¬ÎÒÃÇÔÙÀ´ÊÔÊÔcythonÌṩµÄ¾²Ì¬ÀàÐÍ(static typing)£¬ÐÞ¸Äcython_example.pyxµÄºËÐÄ´úÂë£¬Ìæ»»f()ºÍintegrate_f()µÄʵÏÖÈçÏ£º
def f(double
x): # ²ÎÊý¾²Ì¬ÀàÐÍ
return x**2-x
def integrate_f(double a, double b, int N):
cdef int i
cdef double s, dx
s = 0
dx = (b-a)/N
for i in range(N):
s += f(a+i*dx)
return s * dx |
È»ºóÖØÐÂÔËÐÐÉÏÃæµÄµÚÈý ËIJ½£º½á¹ûÈçÏÂ
call f cost:
0.042387008667
call integrate_f cost: 0.958620071411 |
ÉÏÃæµÄ´úÂ룬ֻÊǶԲÎÊýÒýÈëÁ˾²Ì¬ÀàÐÍÅжϣ¬ÏÂÃæ¶Ô·µ»ØÖµÒ²ÒýÈ뾲̬ÀàÐÍÅжϡ£
Ìæ»»f()ºÍintegrate_f()µÄʵÏÖÈçÏ£º
cdef double
f(double x): # ·µ»ØÖµÒ²ÓÐÀàÐÍÅжÏ
return x**2-x
cdef double integrate_f(double a, double b, int
N):
cdef int i
cdef double s, dx
s = 0
dx = (b-a)/N
for i in range(N):
s += f(a+i*dx)
return s * dx |
È»ºóÖØÐÂÔËÐÐÉÏÃæµÄµÚÈý ËIJ½£º½á¹ûÈçÏÂ
call f cost:
1.19209289551e-06
call integrate_f cost: 0.187038183212 |
Amazing!
pypy
pypyÊÇCPythonµÄÒ»¸öÌæ´úʵÏÖ£¬Æä×îÖ÷ÒªµÄÓÅÊÆ¾ÍÊÇpypyµÄËÙ¶È£¬ÏÂÃæÊǹÙÍøµÄ²âÊÔ½á¹û£º

ÔÚʵ¼ÊÏîÄ¿ÖвâÊÔ£¬pypy´ó¸Å±ÈcpythonÒª¿ì3µ½5±¶!pypyµÄÐÔÄÜÌáÉýÀ´×ÔJIT Compiler¡£ÔÚǰÎÄÌáµ½googleµÄUnladen
Swallow ÏîĿҲÊÇÏëÔÚCPythonÖÐÒýÈëJIT£¬ÔÚÕâ¸öÏîĿʧ°Üºó£¬ºÜ¶à¿ª·¢ÈËÔ±¶¼¿ªÊ¼¼ÓÈëpypyµÄ¿ª·¢ºÍÓÅ»¯¡£ÁíÍâpypyÕ¼ÓõÄÄÚ´æ¸üÉÙ£¬¶øÇÒÖ§³Östackless£¬»ù±¾µÈͬÓÚг̡£
pypyµÄȱµãÔÚÓÚ¶ÔCÀ©Õ¹·½ÃæÖ§³ÖµÄ²»Ì«ºÃ£¬ÐèҪʹÓÃCFFiÀ´×öbinding¡£¶ÔÓÚʹÓù㷺µÄlibraryÀ´Ëµ£¬Ò»°ã¶¼»áÖ§³Öpypy£¬µ«ÊÇСÖڵġ¢»òÕß×ÔÐпª·¢µÄCÀ©Õ¹¾ÍÐèÒªÖØÐ·â×°ÁË¡£
ChangeLog
2017.03.10 Ôö¼ÓÁ˶Ô__slots__µÄ½éÉÜ
references
±à³ÌÓïÑÔbenchmark
pythonÊôÐÔ²éÕÒ
python profiler
yappi
greenletprofiler
python-profiling-tools
python C API
cython
Pyrex
cython document
pypy
|