IPã«ã¡ã©ããå®æçã«ç»åãååŸããéåžžã«ã·ã³ãã«ãªããã°ã©ã ããããŸãã ãã®ããã°ã©ã ã®ã¯ãŒãã³ã°ã»ãããå調ã«æé·ããããšã«æ°ã¥ããŸããã ãã®åé¡ãåçŸããå°ããªããã°ã©ã ãäœæããŸããã
import requests
from memory_profiler import profile
<strong i="6">@profile</strong>
def lol():
print "sending request"
r = requests.get('http://cachefly.cachefly.net/10mb.test')
print "reading.."
with open("test.dat", "wb") as f:
f.write(r.content)
print "Finished..."
if __name__=="__main__":
for i in xrange(100):
print "Iteration", i
lol()
ã¡ã¢ãªäœ¿çšéã¯ãåå埩ã®æåŸã«åºåãããŸãã ããã¯ãµã³ãã«åºåã§ãã
*å埩0 *
Iteration 0
sending request
reading..
Finished...
Filename: test.py
Line # Mem usage Increment Line Contents
================================================
5 12.5 MiB 0.0 MiB <strong i="12">@profile</strong>
6 def lol():
7 12.5 MiB 0.0 MiB print "sending request"
8 35.6 MiB 23.1 MiB r = requests.get('http://cachefly.cachefly.net/10mb.test')
9 35.6 MiB 0.0 MiB print "reading.."
10 35.6 MiB 0.0 MiB with open("test.dat", "wb") as f:
11 35.6 MiB 0.0 MiB f.write(r.content)
12 35.6 MiB 0.0 MiB print "Finished..."
*å埩1 *
Iteration 1
sending request
reading..
Finished...
Filename: test.py
Line # Mem usage Increment Line Contents
================================================
5 35.6 MiB 0.0 MiB <strong i="17">@profile</strong>
6 def lol():
7 35.6 MiB 0.0 MiB print "sending request"
8 36.3 MiB 0.7 MiB r = requests.get('http://cachefly.cachefly.net/10mb.test')
9 36.3 MiB 0.0 MiB print "reading.."
10 36.3 MiB 0.0 MiB with open("test.dat", "wb") as f:
11 36.3 MiB 0.0 MiB f.write(r.content)
12 36.3 MiB 0.0 MiB print "Finished..."
ã¡ã¢ãªäœ¿çšéã¯å埩ããšã«å¢å ããããã§ã¯ãããŸãããã requests.get
ãã¡ã¢ãªäœ¿çšéãå¢å ãããåå ã§ãããå¢å ãç¶ããŸãã
**å埩99 **ã«ãããããã¯ã¡ã¢ãªãããã¡ã€ã«ãã©ã®ããã«èŠãããã§ãã
Iteration 99
sending request
reading..
Finished...
Filename: test.py
Line # Mem usage Increment Line Contents
================================================
5 40.7 MiB 0.0 MiB <strong i="23">@profile</strong>
6 def lol():
7 40.7 MiB 0.0 MiB print "sending request"
8 40.7 MiB 0.0 MiB r = requests.get('http://cachefly.cachefly.net/10mb.test')
9 40.7 MiB 0.0 MiB print "reading.."
10 40.7 MiB 0.0 MiB with open("test.dat", "wb") as f:
11 40.7 MiB 0.0 MiB f.write(r.content)
12 40.7 MiB 0.0 MiB print "Finished..."
ããã°ã©ã ãçµäºããªãéããã¡ã¢ãªäœ¿çšéã¯äœäžããŸããã
ãã°ã¯ãããŸããããããšããŠãŒã¶ãŒãšã©ãŒã§ããïŒ
ãããäžããŠãããããã®è©³çŽ°ãæäŸããŠãããŠããããšãïŒ
æããŠãã ãããã¡ã¢ãªäœ¿çšéããã€ãæžå°ããã®ãèŠãããšããããŸããïŒ
ã¡ã¢ãªäœ¿çšéãæžå°ããã®ãèŠãããšããããŸããã Pythonã®ã¬ããŒãžã³ã¬ã¯ã¿ãŒãšé¢ä¿ãããã®ã§ã¯ãªãããšæã£ãŠããã®ã§ããããããããããéå§ããæ©äŒããªãã£ãã®ã§ãããŠã³ããŒããããã³ã«gc.collect()
ãžã®åŒã³åºããè¿œå ããŸããã ããã¯äœã®éãããããŸããã§ããã
ãã®åé¡ã解決ãããçç±ãèããŠãããã§ããïŒ
ç§ã®äŒç€Ÿã§ãåãåé¡ãçºçããŸããããpypyã䜿çšãããšããã«æ·±å»ã«ãªããŸãã ã³ãŒãããŒã¹ã§ãã®åé¡ã®åå ãpython-requestsãŸã§è¿œè·¡ããã®ã«æ°æ¥ãè²»ãããŸããã
ãã®åé¡ã®æ·±å»ãã匷調ããããã«ãã¡ã¢ãªãããã¡ã€ã©ãŒãå®è¡ãããšãã®ãµãŒããŒããã»ã¹ã®1ã€ãã©ã®ããã«èŠãããã®ã¹ã¯ãªãŒã³ã·ã§ããã次ã«ç€ºããŸãã
http://cl.ly/image/3X3G2y3Y191h
ãã®åé¡ã¯éåžžã®cpythonã§ãåŒãç¶ãçºçããŸãããããã»ã©ç®ç«ã¡ãŸããã ãããããããããã®åé¡ãå ±åãããŠããªãçç±ã§ããããã®ã©ã€ãã©ãªãé·å¹Žã®ããã»ã¹ã«å©çšããŠãã人ã ã«æ·±å»ãªçµæããããããŠããŸãã
ãã®æç¹ã§ããµãããã»ã¹ã§curlã䜿çšããããšãæ€èšããã®ã«ååå¿ æ»ã§ãã
ããªãã®èããšãããã培åºçã«èª¿æ»ããããã©ãããæããŠãã ããã ããã§ãªããã°ãç§ã¯python-requestsãããã·ã§ã³ã¯ãªãã£ã«ã«ãªã¢ããªã±ãŒã·ã§ã³ïŒäŸïŒãã«ã¹ã±ã¢é¢é£ãµãŒãã¹ïŒã«äœ¿çšããã«ã¯å±éºããããšèããŠããŸãã
ããããšãã
-ããã
éã¢ã¯ãã£ãã®ããééãããŸããã ç§ãã¡ãæ£ããæ¹åã«åããããã®æçšãªèšºæãæäŸã§ãããšæãããå Žåã¯ãåéãããŠããã ããŸãã
ããŠãããã§ã¯ç§ã«æäŒãããŠãã ããã
ãã®åé¡ã®èª¿æ»ã容æã«ããããã«ãå°ããªgitãªããžããªãäœæããŸããã
https://github.com/mhjohnson/memory-profiling-requests
çæãããã°ã©ãã®ã¹ã¯ãªãŒã³ã·ã§ããã¯æ¬¡ã®ãšããã§ãã
http://cl.ly/image/453h1y3a2p1r
ã圹ã«ç«ãŠãã°ïŒ äœãééã£ãããšãããå Žåã¯ãç¥ãããã ããã
-ããã
ããããšããããïŒ ããã調ã¹å§ããŸãã ã¹ã¯ãªãããå®è¡ããæåã®æ°åïŒããã³ç§ãè©ŠããããªãšãŒã·ã§ã³ïŒã¯ããããç°¡åã«åçŸã§ããããšã瀺ããŠããŸãã ç§ã¯ä»ããã§éã³å§ããªããã°ãªããªãã€ããã§ãã
ãããã£ãŠãããã¯çŽ0.1MB /ãªã¯ãšã¹ãã§å¢å ããŸãã profile
ãã³ã¬ãŒã¿ãäœã¬ãã«ã®ã¡ãœããã«è²Œãä»ããŠã¿ãŸããããåºåããªã¢ãŒãã§åœ¹ç«ã€ã«ã¯é·ãããŸãã0.1ãããé«ãééã䜿çšãããšãå
šäœçãªäœ¿çšç¶æ³ã远跡ããã ãã§ãããã©ãŒãã³ã¹ããšã§ã¯ãªãããã§ããã©ã€ã³ã®äœ¿çšæ³ã mprofãããåªããããŒã«ã¯ãããŸããïŒ
ããã§ã代ããã«ãåºåã| ag '.*0\.[1-9]+ MiB.*'
ã«ãã€ãããŠãã¡ã¢ãªãè¿œå ãããè¡ãååŸãã profile
ãã³ã¬ãŒã¿ãSession#send
ã åœç¶ã®ããšãªããããã®ã»ãšãã©ã¯HTTPAdapter#send
ãžã®åŒã³åºãããæ¥ãŠããŸãã ãããã®ç©Žãäžã£ãŠè¡ã
ãããŠä»ãããã¯ãã¹ãŠL355ã®conn.urlopen
ãšHTTPAdapter#get_connection
ãžã®åŒã³åºãããæ¥ãŠããŸãã get_connection
ãè£
食ãããšã PoolManager#connection_from_url
åŒã³åºããšãã«7åã¡ã¢ãªãå²ãåœãŠãããŸãã urllib3ããè¿ãããHTTPResponse
ã«ãã£ãŠå€§éšåãããªã¬ãŒãããŠããããšãèãããšãäºåŸã«ã¡ã¢ãªã確å®ã«è§£æŸãããªãããã«ããããã«ããããã䜿çšããŠè¡ãå¿
èŠãããããšããããã©ããã確èªããŸãã ãããåŠçããè¯ãæ¹æ³ãèŠã€ãããªãå Žåã¯ãurllib3ã調ã¹å§ããŸãã
@ sigmavirus24ãããŒã ãããä»äºïŒ ã³ãŒãå
ã®ãããã¹ããããç¹å®ããããã§ãã
ã©ã®ãªããžã§ã¯ããã¡ã¢ãªãªãŒã¯ã®åå ã§ãããã远跡ããããšã«é¢ããŠã¯ã次ã®ããã«objgraphã䜿çšããããšã§ããã€ãã®è¿œå ã®ãã³ããåŸãããšãã§ããŸãã
import gc
import objgraph
# garbage collect first
gc.collect()
# print most common python types
objgraph.show_most_common_types()
ã¬ã ã¯ç§ãäœããã®åœ¢ã§å©ããããšãã§ãããã©ããç¥ã£ãŠããŸãã
-ããã
ç¯äººã«ã€ããŠã®ç§ã®æåã®æšæž¬ã¯ããœã±ãããªããžã§ã¯ãã§ãããã ããã¯PyPyã§ãããæªãçç±ã説æããã§ããã...
ç§ã¯ä»ç©ºæž¯ã«åº§ã£ãŠããŸãããããŠç§ã¯ããã«æ°æéå¹³éã«ããŸãã ç§ã¯ããããä»å€ããŸãã¯æœåšçã«ä»é±åŸåãŸã§ïŒæ¬¡ã®é±æ«/é±ã§ãªããã°ïŒããã«å°éããããšã¯ã§ããŸããã ãããŸã§ã®ãšãããåãåã£ãHTTPResponse
release_conn
ãŸããã gc.get_referents
ãGCã«å€±æããŠããå¯èœæ§ã®ããResponseãªããžã§ã¯ãã®å
容ã確èªããŸããã å
ã®httplibHTTPResponseïŒ _original_response
ãšããŠä¿åãããïŒ get_referents
å ±åãããã®ããïŒã«ã¯ïŒããããŒçšã®ïŒé»åã¡ãŒã«ã¡ãã»ãŒãžã®ã¿ãããããã®ä»ã¯ãã¹ãŠæååãŸãã¯èŸæžïŒãŸãã¯å€åãªã¹ãïŒããœã±ããã®å Žåãã¬ããŒãžã³ã¬ã¯ã·ã§ã³ãè¡ãããªãå ŽæãããããŸããã
ãŸãã Session#close
䜿çšããŠãïŒæåã«æ©èœAPIã®ä»£ããã«ã»ãã·ã§ã³ã䜿çšããããã«ã³ãŒããäœæããŸããïŒã圹ã«ç«ã¡ãŸããïŒããã«ãããæ¥ç¶ããŒã«ãã¯ãªã¢ããPoolManagerãã¯ãªã¢ãããŸãïŒã ãããã£ãŠããã1ã€èå³æ·±ãã®ã¯ã PoolManager#connection_from_url
ãåŒã³åºãããæåã®æ°åã§çŽ0.8 MBïŒ0.1ãäžãããåãïŒãè¿œå ããããšã§ããã ã€ãŸããæ倧3MBãè¿œå ãããŸãããæ®ãã¯HTTPAdapter#send
conn.urlopen
ããååŸãããŸãã å¥åŠãªããšã«ã gc.set_debug(gc.DEBUG_LEAK)
ã䜿çšãããšã gc.garbage
ã¯å¥åŠãªèŠçŽ ãããã€ããããŸãã [[[...], [...], [...], None], [[...], [...], [...], None], [[...], [...], [...], None], [[...], [...], [...], None]]
ãããªãã®ããããäºæ³ã©ããgc.garbage[0] is gc.garbage[0][0]
ãªã®ã§ãæ
å ±ã¯ãŸã£ãã圹ã«ç«ã¡ãŸããã æ©äŒãããã°ãobjgraphãè©ŠããŠã¿ãå¿
èŠããããŸãã
ããã§ç§ã¯urllib3ãæãäžããŠãä»æããã«æ©ããŠãµã®ã®ç©Žããã©ããŸããã ConnectionPool#urlopen
ãããã¡ã€ã«ãäœæãããšããã ConnectionPool#_make_request
ã ãã®æç¹ã§ã urllib3/connectionpool.py
306è¡ç®ãš333è¡ç®ãã倧éã®ã¡ã¢ãªãå²ãåœãŠãããŠããŸãã L306ã¯self._validate_conn(conn)
ãL333ã¯conn.getresponse(buffering=True)
ã§ãã getresponse
ã¯ã HTTPConnectionã®httplib
ã¡ãœããã§ãã ãããããã«ãããã¡ã€ãªã³ã°ããã®ã¯ç°¡åã§ã¯ãããŸããã _validate_conn
ãèŠããšããããåŒãèµ·ããè¡ã¯conn.connect()
ãããããã¯å¥ã®HTTPConnectionã¡ãœããã§ãã connect
ã¯ãã»ãŒç¢ºå®ã«ãœã±ãããäœæãããŠããå Žæã§ãã ã¡ã¢ãªãããã¡ã€ãªã³ã°ãç¡å¹ã«ããŠprint(old_pool)
ãHTTPConnectionPool#close
ã«è²Œãä»ãããšãäœãåºåãããŸããã ã»ãã·ã§ã³ãç Žæ£ããããããå®éã«ã¯ããŒã«ãéããŠããªãããã§ãã ãããã¡ã¢ãªãªãŒã¯ã®åå ã ãšæããŸãã
ããããããã°ããã®ãæäŒãããã®ã§ãããç§ã¯ä»æ¥ãšææ¥IRCã«åºå ¥ãããŸãã
ãããã£ãŠããããããã«ãã¬ãŒã¹ãããšã _make_request
ãè£
食ããããŸãŸïŒ profile
ïŒ python
ãéããã»ãã·ã§ã³ãäœæãããšã10ç§ãŸãã¯20ç§ããšã«ãªã¯ãšã¹ããè¡ãããŸãïŒåãURLã§ãïŒãconnãåé€ããããšèŠãªãããŠããã®ã§ã VerifiedHTTPSConnection
ãéããããŠåå©çšãããŸãã ããã¯ãåºã«ãªããœã±ããã§ã¯ãªãã connection
ã¯ã©ã¹ãåå©çšãããããšãæå³ããŸãã close
ã¡ãœããã¯ã httplib.HTTPConnection
ïŒL798ïŒã§äœ¿çšãããã¡ãœããã§ãã ããã«ããããœã±ãããªããžã§ã¯ããéãããã[ãªã]ã«èšå®ãããŸãã 次ã«ãææ°ã®httplib.HTTPResponse
éããŸãïŒãããŠNoneã«èšå®ããŸãïŒã VerifiedHTTPSConnection#connect
ããããã¡ã€ãªã³ã°ããå Žåãäœæ/ãªãŒã¯ããããã¹ãŠã®ã¡ã¢ãªã¯urllib3.util.ssl_.ssl_wrap_socket
ãŸãã
ãããã£ãŠããããèŠããšãmemory_profilerãã¡ã¢ãªäœ¿çšéãå ±åããããã«äœ¿çšããŠããã®ã¯ãããã»ã¹ã®åžžé§ã»ãããµã€ãºïŒrssïŒã§ãã ããã¯RAMå ã®ããã»ã¹ã®ãµã€ãºã§ãïŒvmsããŸãã¯ä»®æ³ã¡ã¢ãªãµã€ãºã¯mallocãšé¢ä¿ããããŸãïŒã®ã§ãä»®æ³ã¡ã¢ãªããªãŒã¯ããŠãããã©ããããŸãã¯ããŒãžãå²ãåœãŠãããŠããã ããã©ããã確èªããŠããŸãç§ãã¡ã倱ã£ãŠããªãèšæ¶ã
ãããŸã§äœ¿çšããŠãããã¹ãŠã®URLãæ€èšŒæžã¿ã®HTTPSã䜿çšããŠããããšãèãããšã http://google.com
ã䜿çšããããã«åãæ¿ããŸãããã¡ã¢ãªã¯åžžã«å¢å ããŠããŸãããæ¶è²»éã¯çŽ11ã14MiBå°ãªãããã§ããæŠããŠã ããã§ããã¹ãŠãconn.getresponse
è¡ã«æ»ããŸãïŒãããŠä»ã§ã¯ããã»ã©ã§ã¯ãããŸãããconn.request
ïŒã
èå³æ·±ãã®ã¯ãç§ãæ åœè ã§èª¿ã¹ãŠãããšããVMSã¯ããŸãæé·ããŠããªãããã«èŠããããšã§ãã RSSå€ã®ä»£ããã«ãã®å€ãè¿ãããã«mprofããŸã å€æŽããŠããŸããã çå®ã«å¢å ããVMSã¯ç¢ºãã«ã¡ã¢ãªãªãŒã¯ã瀺ããŸãããRSSã¯åã«å€æ°ã®mallocã§ããå¯èœæ§ããããŸãïŒããã¯å¯èœã§ãïŒã ã»ãšãã©ã®ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ïŒç§ãæ£ããç解ããŠããå ŽåïŒã¯RSSãç±å¿ã«åå©çšããªããããå¥ã®ã¢ããªã±ãŒã·ã§ã³ããŒãžã«é害ãçºçããä»ã«å²ãåœãŠãå ŽæããªããªããŸã§ãRSSã¯çž®å°ããŸããïŒã§ãããšããŠãïŒã ãšã¯ãããå®åžžç¶æ ã«éããããšãªãäžè²«ããŠå¢å ããŠããå Žåããããrequests / urllib3ãªã®ãããããšãåãªãã€ã³ã¿ãŒããªã¿ãŒãªã®ãã¯ããããŸããã
ãŸããããã¯ç§ãã¡ã®åé¡ã§ã¯ãªããšèãå§ããŠããã®ã§ãurllib2 / httplibãçŽæ¥äœ¿çšãããšã©ããªãããèŠãŠãããŸãã ç§ã®ç¥ãéãã Session#close
ãã¹ãŠã®ãœã±ãããé©åã«éããããããžã®åç
§ãåé€ããŠãGCã§ããããã«ããŸãã ããã«ããœã±ãããæ¥ç¶ããŒã«ã«çœ®ãæããå¿
èŠãããå Žåããåãããšãèµ·ãããŸãã SSLSocketã§ãããã¬ããŒãžã³ã¬ã¯ã·ã§ã³ãé©åã«åŠçããŠããããã§ãã
ãããã£ãŠãurllib2ã¯äžè²«ããŠ13.3MiBååŸã§ãã©ããã©ã€ã³ã«ãªã£ãŠããããã§ãã éãã¯ããã°ãããããšURLErrorã§äžè²«ããŠã¯ã©ãã·ã¥ãããããtry / exceptã§ã©ããããå¿ èŠããã£ãããšã§ãã ã§ãããããã°ãããããšå®éã«ã¯äœãããŠããªãã®ãããããŸããã
@ sigmavirus24ããªãã¯ãããç²ç ããŠããŸãïŒ :)
ããŒã... Pythonã¯ã¡ã¢ãªã解æŸããŠããèªäœã§åå©çšããã ãã§ãããã·ã¹ãã ã¯ããã»ã¹ãçµäºãããŸã§ã¡ã¢ãªãåãæ»ããŸããã ãããã£ãŠã13.3MiBã§èŠããããã©ããã©ã€ã³ã¯ãurllib3ãšã¯ç°ãªããurllib2ã«ã¡ã¢ãªãªãŒã¯ãååšããªãããšã瀺ããŠãããšæããŸãã
åé¡ãurllib3ã«åãåããããšãã§ããããšã確èªãããšããã§ãããã urllib2ã§ãã¹ãããããã«äœ¿çšããŠããã¹ã¯ãªãããå ±æã§ããŸããïŒ
ã ããç§ã¯ãããHTTPConnection
ãªããžã§ã¯ããšã¯äœã®é¢ä¿ããªãã®ã ããããšæãå§ããŠããŸãã ããããªãããããããªã
import sys
import requests
s = requests.Session()
r = s.get('https://httpbin.org/get')
print('Number of response refs: ', sys.getrefcount(r) - 1)
print('Number of session refs: ', sys.getrefcount(s) - 1)
print('Number of raw refs: ', sys.getrefcount(r.raw) - 1)
print('Number of original rsponse refs: ', sys.getrefcount(r.raw._original_response) - 1)
æåã®3ã€ã¯1ãæåŸã¯3ãåºåããã¯ãã§ãã[1] HTTPConnectionã«ã¯_original_response
ãžã®åç
§ã§ãã_HTTPConnection__response
ããããšããã§ã«ç¢ºèªããŸããã ã ããç§ã¯ãã®æ°ã3ã«ãªããšæã£ãŠããŸãããç§ãç解ã§ããªãã®ã¯ã3çªç®ã®ã³ããŒãžã®åç
§ãä¿æããŠãããã®ã§ãã
ããã«åš¯æ¥œã®ããã«ã以äžãè¿œå ããŸã
import gc
gc.set_debug(gc.DEBUG_STATS | gc.DEBUG_UNCOLLECTABLE)
ã¹ã¯ãªããã®æåã«ã ãªã¯ãšã¹ããåŒã³åºããåŸãå°éã§ããªããªããžã§ã¯ãã2ã€ãããŸããããã¯èå³æ·±ããã®ã§ãããåéã§ããªããã®ã¯ãããŸããã§ããã ãããæäŸãããã¹ã¯ãªãã@mhjohnsonã«è¿œå ããå°éäžèœãªè¡ã®åºåããã£ã«ã¿ãªã³ã°ãããšã
ãã¹ãurllib3ã«@mhjohnsonã¯ãã¡ããã©ã«ãé»è©±ã眮ãæããrequests.get
ãšurllib2.urlopen
ïŒãŸããç§ã¯ãããããã£ãŠããã¯ãã§ãr.read()
ãç§ã¯ãããŸããã§ããïŒã
ããã§ã @ mhjohnsonã®ä»¥åã®ææ¡ãå©çšããŠã objgraph
ã䜿çšããŠä»ã®åç
§ãã©ãã«ãããã調ã¹ãŸããããobjgraphã¯ãããèŠã€ããããªãããã§ãã è¿œå ããïŒ
objgraph.show_backrefs([r.raw._original_response], filename='requests.png')
äžèšã®ã¹ã¯ãªãã2ã®ã³ã¡ã³ãã§ã次ã®ããã«ãªããŸããã
ããã¯ããããžã®åç
§ã2ã€ããããšã瀺ããŠããã ãã§ãã sys.getrefcount
ãã©ã®ããã«æ©èœãããã«ã€ããŠãä¿¡é Œã§ããªãäœããããã®ã ãããã
ã ãããããã¯èµ€ããã·ã³ã§ãã urllib3.response.HTTPResponse
ã¯_original_response
ãš_fp
äž¡æ¹ããããŸãã ããã_HTTPConection__response
ãšçµã¿åããããšã3ã€ã®åç
§ãåŸãããŸãã
ãããã£ãŠã urllib3.response.HTTPResponse
ã«ã¯_pool
å±æ§ããããããã¯PoolManager
ã«ãã£ãŠãåç
§ãããŸãã åæ§ã«ããªã¯ãšã¹ãã®äœæã«äœ¿çšãããHTTPAdapter
ã«ã¯ã Response
ãªã¯ãšã¹ãã®ãªã¿ãŒã³ã«é¢ããåç
§ããããŸãã å€å誰ãä»ã®äººãããããäœããç¹å®ããããšãã§ããŸãïŒ
ãããçæããã³ãŒãã¯æ¬¡ã®ãšããã§ãïŒ https ïŒ
@ sigmavirus24
ãããç§ã¯ãã®æåŸã®ã°ã©ãã£ãã¯ã§å°ãè¿·åã«ãªããŸããã ãããããã³ãŒãããŒã¹ãããããããªãããããã¡ã¢ãªãªãŒã¯ã®ãããã°ã«ç²ŸéããŠããªãããã§ãã
ããªãã®ã°ã©ãã£ãã¯ã®ãã®ã¹ã¯ãªãŒã³ã·ã§ããã§ç§ãèµ€ãç¢å°ã§æããŠããã®ã¯ã©ã®ãªããžã§ã¯ããç¥ã£ãŠããŸããïŒ
http://cl.ly/image/3l3g410p3r1C
åãããã«ãã£ãããšå¢å ããã¡ã¢ãªäœ¿çšéã瀺ãã³ãŒããååŸããããšãã§ããŸãã
python3ã§ã¯ãurllib3 / requestsãurllib.request.urlopenã«çœ®ãæããŸãã
ããã§å€æŽãããã³ãŒãïŒ https ïŒ
ã±ãã³ã»ããŒã¯
é»è©±çªå·ïŒ925.271.7005 | 20milliseconds.com
21:28ææã2014幎11æ3æ¥ã«ã¯ããã·ã¥ãŒã»ãžã§ã³ãœã³[email protected]
æžããŸããïŒ
@ sigmavirus24 https://github.com/sigmavirus24
ãããç§ã¯ãã®æåŸã®ã°ã©ãã£ãã¯ã§å°ãè¿·åã«ãªããŸããã ãã¶ãç§ãããªããã
ã³ãŒãããŒã¹ãããç¥ã£ãŠããããã¡ã¢ãªã®ãããã°ã«æ £ããŠããªã
æŒããŸãããããèµ€ãç¢å°ã§æããŠãããªããžã§ã¯ããç¥ã£ãŠããŸãã
ããªãã®ã°ã©ãã£ãã¯ã®ãã®ã¹ã¯ãªãŒã³ã·ã§ããã§ã¯ïŒ
http://cl.ly/image/3l3g410p3r1Câ
ãã®ã¡ãŒã«ã«çŽæ¥è¿ä¿¡ããããGitHubã§è¡šç€ºããŠãã ãã
https://github.com/kennethreitz/requests/issues/1685#issuecomment -61595362
ã
ç§ãç¥ãéãã
æ¥ç¶ïŒããããŒãéããïŒäŸïŒhttpsïŒ//api.twilio.com/2010-04-01.jsonïŒ
ã¡ã¢ãªäœ¿çšéã倧å¹
ã«å¢å ããããšã¯ãããŸããã èŠåã¯
è€æ°ã®ç°ãªãèŠå ããããç§ã¯ããããœã±ããã ãšæã£ãŠããŸã
é¢é£ããåé¡ã
ã±ãã³ã»ããŒã¯
é»è©±çªå·ïŒ925.271.7005 | 20milliseconds.com
2014幎11æ3æ¥æææ¥ååŸ9æ43åãKevin [email protected]ã¯æ¬¡ã®ããã«æžããŠããŸãã
åãããã«ãã£ãããšå¢å ããã¡ã¢ãªäœ¿çšéã瀺ãã³ãŒããååŸããããšãã§ããŸãã
python3ã§ã¯ãurllib3 / requestsãurllib.request.urlopenã«çœ®ãæããŸããããã§å€æŽãããã³ãŒãïŒ
https://gist.github.com/kevinburke/f99053641fab0e2259f0ã±ãã³ã»ããŒã¯
é»è©±çªå·ïŒ925.271.7005 | 20milliseconds.com21:28ææã2014幎11æ3æ¥ã«ã¯ããã·ã¥ãŒã»ãžã§ã³ãœã³[email protected]
æžããŸããïŒ@ sigmavirus24 https://github.com/sigmavirus24
ãããç§ã¯ãã®æåŸã®ã°ã©ãã£ãã¯ã§å°ãè¿·åã«ãªããŸããã ãã¶ãç§ã
ã³ãŒãããŒã¹ãããç¥ããªãããŸããããã°ã«ç²ŸéããŠããªã
ã¡ã¢ãªãªãŒã¯ããããèµ€ãç¢å°ã§æããŠãããªããžã§ã¯ããç¥ã£ãŠããŸãã
ããªãã®ã°ã©ãã£ãã¯ã®ãã®ã¹ã¯ãªãŒã³ã·ã§ããã§ã¯ïŒ
http://cl.ly/image/3l3g410p3r1Câ
ãã®ã¡ãŒã«ã«çŽæ¥è¿ä¿¡ããããGitHubã§è¡šç€ºããŠãã ãã
https://github.com/kennethreitz/requests/issues/1685#issuecomment -61595362
ã
ã¡ã¿ã¿ã€ããžã®åç
§ã®æ°ã§ããããã«æã@mhjohnson type
ã«ãã£ãŠobject
ã¿ã€ãã§ããtype
ã èšãæããã°ããããobject
ãŸãã¯type
ã®ããããã®åç
§ã§ãããšæããŸãããããããããŸããã ãããã«ãããããããé€å€ããããšãããšãã°ã©ãã¯2ããŒãã®ããã«ãªããŸãã
ãŸããããã»ã¹ãéåžžæ°æ¥éå®è¡ãããWebã¯ããŒã«ã·ã¹ãã ã§ãªã¯ãšã¹ãã䜿çšããããããã®ã¡ã¢ãªãªãŒã¯ã®åé¡ã«ã€ããŠãéåžžã«å¿é ããŠããŸãã ãã®åé¡ã«ã€ããŠäœãé²å±ã¯ãããŸããïŒ
@mhjohnsonãšäžç·ã«ããã«æéãè²»ãããåŸãGCãPyPyã®ãœã±ãããåŠçããæ¹æ³ã«é¢é£ãã@kevinburkeçè«ã確èªã§ããŸãã
3c0b94047c1ccfca4ac4fââ2fe32afef0ae314094eã³ãããã¯èå³æ·±ããã®ã§ãã å ·äœçã«ã¯ã httpsïŒ//github.com/kennethreitz/requests/blob/master/requests/models.py#L736
ã³ã³ãã³ããè¿ãåã«self.raw.release_conn()
åŒã³åºããšãPyPyã§äœ¿çšãããã¡ã¢ãªã倧å¹
ã«åæžãããŸãããããŸã æ¹åã®äœå°ããããŸãã
ãŸãã@ sigmavirus24ã§ãèšåãããŠããããã«ãã»ãã·ã§ã³ã¯ã©ã¹ãšå¿çã¯ã©ã¹ã«é¢é£ãã.close()
åŒã³åºããææžåãããšãããšæããŸãã ã»ãšãã©ã®å Žåãã¡ãœããã¯æé»çã«åŒã³åºãããªãããããŠãŒã¶ãŒã¯ãããã®ã¡ãœããã«æ³šæããå¿
èŠããããŸãã
ãã®ãããžã§ã¯ãã®QAã«é¢ãã質åãææ¡ããããŸãã ãã¹ãã®æŽåæ§ã確ä¿ããããã«CIã䜿çšããªãçç±ãã¡ã³ããã«å°ããŠãããã§ããïŒ CIããããšãããã©ãŒãã³ã¹/ã¡ã¢ãªã®äœäžããããã¡ã€ãªã³ã°ããŠè¿œè·¡ã§ãããã³ãããŒã¯ãã¹ãã±ãŒã¹ãäœæããããšãã§ããŸãã
ãã®ãããªã¢ãããŒãã®è¯ãäŸã¯ãpqãããžã§ã¯ãã«ãããŸãã
https://github.com/malthe/pq/blob/master/pq/tests.py#L287
ããã«é£ã³ä¹ã£ãŠå©ããããšæ±ºå¿ãããã¹ãŠã®äººã«æè¬ããŸãïŒ
ãããåŒãèµ·ãããŠããä»ã®çè«ã調æ»ãç¶ããŸãã
@stasç§ã¯1ã€ã®ããšã
ã»ãšãã©ã®å Žåãã¡ãœããã¯æé»çã«åŒã³åºãããªãããããŠãŒã¶ãŒã¯ãããã®ã¡ãœããã«æ³šæããå¿ èŠããããŸãã
PyPyããã°ããèã«çœ®ããŠãããšããããã®ã¡ãœãããæ瀺çã«åŒã³åºãå¿ èŠã¯ãããŸããã ãœã±ãããªããžã§ã¯ããCPythonã§å°éäžèœã«ãªããšããã¡ã€ã«ãã³ãã«ãéããããšãå«ãèªågcãååŸãããŸãã ããã¯ããããã®ã¡ãœãããææžåããªããšãã䞻匵ã§ã¯ãããŸããããé床ã«çŠç¹ãåœãŠãªãããã«èŠåããŠããŸãã
CIã䜿çšããããšãæå³ããŠããŸãããçŸæç¹ã§ã¯åé¡ãããããã§ã
PyPyããã°ããèã«çœ®ããŠãããšããããã®ã¡ãœãããæ瀺çã«åŒã³åºãå¿ èŠã¯ãããŸããã ãœã±ãããªããžã§ã¯ããCPythonã§å°éäžèœã«ãªããšããã¡ã€ã«ãã³ãã«ãéããããšãå«ãèªågcãååŸãããŸãã ããã¯ããããã®ã¡ãœãããææžåããªããšãã䞻匵ã§ã¯ãããŸããããé床ã«çŠç¹ãåœãŠãªãããã«èŠåããŠããŸãã
ããã§Pythonã«ã€ããŠèª¬æããéšåãé€ããŠãç§ã¯ããªãã®èšãããšã«åæããŸãã è°è«ãå§ãããã¯ãããŸãããã_The Zen of Python_ãèªããšãPythonã®æ¹æ³ã¯_Explicit_ã®ã¢ãããŒãããã_Explicit_ã®æ¹ãåªããŠããŸãã ç§ããã®ãããžã§ã¯ãã®å²åŠã«ç²ŸéããŠããªãã®ã§ããããrequests
åœãŠã¯ãŸããªãå Žåã¯ãç§ã®èããç¡èŠããŠãã ããã
æ©äŒãããã°ãã€ã§ãCIãŸãã¯ãã³ãããŒã¯ãã¹ãããæäŒããããŠããã ããŸãã çŸåšã®ç¶æ³ã説æããŠããã ãããããšãããããŸãã
ã ãããæ©èœçãªAPIã䜿ã£ãŠãããšãã«åé¡ã®åå ãèŠã€ãããšæããŸãã ããããªãããããããªã
import requests
r = requests.get('https://httpbin.org/get')
print(r.raw._pool.pool.queue[-1].sock)
ãœã±ããã¯ãŸã éããŠããããã§ãã ç§ã_appears_ãšèšãçç±ã¯ãããããŸã _sock
å±æ§ãæã£ãŠããããã§ãã
r.raw._pool.queue[-1].close()
print(repr(r.raw._pool.queue[-1].sock))
None
å°å·ãããŸãã ã€ãŸãã urllib3
ã¯ããã¹ãŠã®HTTPResponse
ã«ãå
ã®æ¥ç¶ããŒã«ãæãå±æ§ãå«ãŸããŠãããšããããšã§ãã æ¥ç¶ããŒã«ã®ãã¥ãŒã«ã¯ãéããããŠããªããœã±ãããæã€æ¥ç¶ããããŸãã æ©èœAPIã®åé¡ã¯ã requests/api.py
ããã«ãããšä¿®æ£ãããŸãã
def request(...):
"""..."""
s = Session()
response = s.request(...)
s.close()
return s
ãã®å Žåã r.raw._pool
ã¯åŒãç¶ãæ¥ç¶ããŒã«ã«ãªããŸããã r.raw._pool.pool
ã¯None
ãŸãã
ããªãããŒãªéšåã¯ã人ã
ãã»ãã·ã§ã³ã䜿çšããŠãããšãã«èµ·ããããšã§ãã ãã¹ãŠã®ãªã¯ãšã¹ãã®åŸã«ã»ãã·ã§ã³ã«close
ãèšå®ããããšã¯ç¡æå³ã§ãããã»ãã·ã§ã³ã®ç®çãæãªããŸãã å®éã«ã¯ãã»ãã·ã§ã³ïŒã¹ã¬ãããªãïŒã䜿çšããã»ãã·ã§ã³ã䜿çšããŠåããã¡ã€ã³ïŒããã³åãã¹ããŒã ãããšãã°https
ïŒã«100ã®èŠæ±ãè¡ãå Žåãã¡ã¢ãªãªãŒã¯ã確èªããã®ã¯ã¯ããã«å°é£ã§ããæ°ãããœã±ãããäœæããããŸã§çŽ30ç§åŸ
ã¡ãŸãã åé¡ã¯ããã§ã«èŠãŠããããã«ã r.raw._pool
ã¯éåžžã«å¯å€ãªãªããžã§ã¯ãã§ãããšããããšã§ãã ããã¯ããªã¯ãšã¹ãã§ããŒã«ãããŒãžã£ã«ãã£ãŠç®¡çãããæ¥ç¶ããŒã«ãžã®åç
§ã§ãã ãããã£ãŠããœã±ããã眮ãæãããããšãïŒã¹ã³ãŒãå
ã§ïŒãŸã å°éå¯èœãªãã¹ãŠã®å¿çããã®ãœã±ãããžã®åç
§ã«çœ®ãæããããŸãã ç§ããã£ãšãããªããã°ãªããªãããšã¯ãæ¥ç¶ããŒã«ãéããåŸããœã±ãããžã®åç
§ããŸã ä¿æãããŠãããã©ãããææ¡ããããšã§ãã åç
§ãä¿æããŠãããã®ãèŠã€ããããšãã§ããã°ã_å®éã®_ã¡ã¢ãªãªãŒã¯ãèŠã€ãããšæããŸãã
ã ããç§ã¯æã£ãŠããããšã1ã€ã®ã¢ã€ãã¢ãå®éã«åç
§ããããææ¡ããobjgraph䜿çšããŠããSSLSocket
ãåŒã³åºããåŸã§requests.get
ãšç§ã¯ãããåŸãŸããïŒ
èå³æ·±ãã®ã¯ã SSLSocket
ãžã®åç
§ã7ã€ããããã§ãããobjgraphãèŠã€ããããšãã§ããåŸæ¹åç
§ã¯2ã€ã ãã§ãããšããããšã§ãã åç
§ã®1ã€ã¯objgraphã«æž¡ããããã®ã§ããããã1ã€ã¯ãããçæããã¹ã¯ãªããã§äœæãããã€ã³ãã£ã³ã°ã§ãããããã§ã3ã€ãŸãã¯4ã€ã¯ãã©ãããæ¥ãã®ãããããªãåç
§ãšããŠèæ
®ãããŠããŸããã
ãããçæããããã®ç§ã®ã¹ã¯ãªããã¯æ¬¡ã®ãšããã§ãã
import objgraph
import requests
r = requests.get('https://httpbin.org/get')
s = r.raw._pool.pool.queue[-1].sock
objgraph.show_backrefs(s, filename='socket.png', max_depth=15, refcounts=True)
䜿çšãã
import objgraph
import requests
r = requests.get('https://httpbin.org/get')
s = r.raw._pool.pool.queue[-1].sock
objgraph.show_backrefs(s, filename='socket-before.png', max_depth=15,
refcounts=True)
r.raw._pool.close()
objgraph.show_backrefs(s, filename='socket-after.png', max_depth=15,
refcounts=True)
socket-after.png
ã¯ããã瀺ããŠããŸãïŒ
ãããã£ãŠãsslãœã±ãããžã®åç
§ã1ã€åé€ããŸãã ããã¯èšã£ãŠãã s._sock
ãåºç€ãšãªãsocket.socket
ã¯éããŠããŸãã
å€æ°ã®é·æå®è¡ãã³ãããŒã¯ãå®è¡ããåŸã次ã®ããšãããããŸããã
close()
åŒã³åºããšãæ瀺çã«åœ¹ç«ã¡ãŸããSession
ã䜿çšããå®äºåŸã«é©åã«éããå¿
èŠããããŸãã ïŒ2326ãããŒãžããŠãã ããgc.collect()
æ瀺çã«åŒã³åºãå¿
èŠããããŸããTL; DR; requests
ã¯è¯ãããã§ãã以äžã«ããã®ã¹ãããããå®è¡ããŠããã°ã©ããããã€ã瀺ããŸãã
import requests
from memory_profiler import profile
<strong i="15">@profile</strong>
def get(session, i):
return session.get('http://stas.nerd.ro/?{0}'.format(i))
<strong i="16">@profile</strong>
def multi_get(session, count):
for x in xrange(count):
resp = get(session, count+1)
print resp, len(resp.content), x
resp.close()
<strong i="17">@profile</strong>
def run():
session = requests.Session()
print 'Starting...'
multi_get(session, 3000)
print("Finished first round...")
session.close()
print 'Done.'
if __name__ == '__main__':
run()
CPythonïŒ
Line # Mem usage Increment Line Contents
================================================
15 9.1 MiB 0.0 MiB <strong i="23">@profile</strong>
16 def run():
17 9.1 MiB 0.0 MiB session = requests.Session()
18 9.1 MiB 0.0 MiB print 'Starting...'
19 9.7 MiB 0.6 MiB multi_get(session, 3000)
20 9.7 MiB 0.0 MiB print("Finished first round...")
21 9.7 MiB 0.0 MiB session.close()
22 9.7 MiB 0.0 MiB print 'Done.'
JITãªãã®PyPyïŒ
Line # Mem usage Increment Line Contents
================================================
15 15.0 MiB 0.0 MiB <strong i="29">@profile</strong>
16 def run():
17 15.4 MiB 0.5 MiB session = requests.Session()
18 15.5 MiB 0.0 MiB print 'Starting...'
19 31.0 MiB 15.5 MiB multi_get(session, 3000)
20 31.0 MiB 0.0 MiB print("Finished first round...")
21 31.0 MiB 0.0 MiB session.close()
22 31.0 MiB 0.0 MiB print 'Done.'
JITã䜿çšããPyPyïŒ
Line # Mem usage Increment Line Contents
================================================
15 22.0 MiB 0.0 MiB <strong i="35">@profile</strong>
16 def run():
17 22.5 MiB 0.5 MiB session = requests.Session()
18 22.5 MiB 0.0 MiB print 'Starting...'
19 219.0 MiB 196.5 MiB multi_get(session, 3000)
20 219.0 MiB 0.0 MiB print("Finished first round...")
21 219.0 MiB 0.0 MiB session.close()
22 219.0 MiB 0.0 MiB print 'Done.'
ç§ãã¡å šå¡ãæåã«æ··ä¹±ããçç±ã®1ã€ã¯ããã³ãããŒã¯ãå®è¡ããã«ã¯ãããå®è£ ããå¥ã®å®è£ ãžã®GCã®åäœãé€å€ããããã«ããã倧ããªã»ãããå¿ èŠã«ãªãããã ãšæããŸãã
ãŸããã¹ã¬ããç°å¢ã§ãªã¯ãšã¹ããå®è¡ããã«ã¯ãã¹ã¬ããã®åäœæ¹æ³ã«ãããããå€ãã®åŒã³åºãã»ãããå¿ èŠã«ãªããŸãïŒè€æ°ã®ã¹ã¬ããããŒã«ãå®è¡ããåŸãã¡ã¢ãªäœ¿çšéã«å€§ããªå€åã¯èŠãããŸããã§ããïŒã
JITã䜿çšããPyPyã«é¢ããŠã¯ãåãåæ°ã®åŒã³åºãã§gc.collect()
ãåŒã³åºããšãã¡ã¢ãªãæ倧30ïŒ
ç¯çŽãããŸããã ãã®ãããJITã®çµæã¯ã誰ããVMã埮調æŽããJITã®ã³ãŒããæé©åããæ¹æ³ã®äž»é¡ã§ããããããã®èª¬æããé€å€ããå¿
èŠããããšæããŸãã
äºè§£ããŸãããåé¡ã¯ãPyPyJITãšçžäºäœçšããã¡ã¢ãªã®åŠçæ¹æ³ã«ããããã«èŠããŸãã PyPyã®å°é家ã«å¬åããã®ã¯è¯ãèããããããŸããïŒ@alexïŒ
ç§ã¯æ¬åœã«ããã®ãããªããšãåŒãèµ·ããå¯èœæ§ã®ããèŠæ±ïŒããã³äŒç€ŸïŒãäœãããŠããã®ãæ³åã§ããŸããã ç°å¢å
ã®PYPYLOG=jit-summary:-
ããŠãã¹ããå®è¡ããçµæã貌ãä»ããããšãã§ããŸããïŒããã»ã¹ãçµäºãããšããã€ãã®ãã®ãåºåãããŸãïŒ
ã圹ã«ç«ãŠãã°ïŒ
Line # Mem usage Increment Line Contents
================================================
15 23.7 MiB 0.0 MiB <strong i="6">@profile</strong>
16 def run():
17 24.1 MiB 0.4 MiB session = requests.Session()
18 24.1 MiB 0.0 MiB print 'Starting...'
19 215.1 MiB 191.0 MiB multi_get(session, 3000)
20 215.1 MiB 0.0 MiB print("Finished first round...")
21 215.1 MiB 0.0 MiB session.close()
22 215.1 MiB 0.0 MiB print 'Done.'
[2cbb7c1bbbb8] {jit-summary
Tracing: 41 0.290082
Backend: 30 0.029096
TOTAL: 1612.933400
ops: 79116
recorded ops: 23091
calls: 2567
guards: 7081
opt ops: 5530
opt guards: 1400
forcings: 198
abort: trace too long: 2
abort: compiling: 0
abort: vable escape: 9
abort: bad loop: 0
abort: force quasi-immut: 0
nvirtuals: 9318
nvholes: 1113
nvreused: 6666
Total # of loops: 23
Total # of bridges: 8
Freed # of loops: 0
Freed # of bridges: 0
[2cbb7c242e8b] jit-summary}
https://launchpad.net/~pypy/+archive/ubuntu/ppaã®ææ°ã®PyPyã䜿çšããŠä¿¡é Œã§ãã32ãããã䜿çšããŠã
31ã®ã³ã³ãã€ã«æžã¿ãã¹ã¯ã䜿çšäžã®200MB以äžã®RAMã説æããŠããŸããã
ããã°ã©ã ã«äœããå
¥ããŠå®è¡ã§ããŸãã
éåžžã«é«ãã¡ã¢ãªã«ããégc.dump_rpy_heap('filename.txt')
䜿çšæ³ïŒ ïŒäžåºŠå®è¡ããå¿
èŠããããŸããããã«ããããã¹ãŠã®ãã³ããçæãããŸãã
GCãç¥ã£ãŠããã¡ã¢ãªïŒã
次ã«ãPyPyãœãŒã¹ããªãŒããã§ãã¯ã¢ãŠãããŠã ./pypy/tool/gcdump.py
filename.txt
ãå®è¡ããçµæã衚瀺ããŸãã
ããããšãïŒ
3æ20å52ç§PMã¹ã¿ãŒã¹SuÅcovã®å2014幎11æ8æ¥ã«ã¯[email protected]
æžããŸããïŒ
ã圹ã«ç«ãŠãã°ïŒ
è¡çªå·ã¡ã¢ãªäœ¿çšéå¢åè¡ã®å 容
15 23.7 MiB 0.0 MiB <strong i="20">@profile</strong> 16 def run(): 17 24.1 MiB 0.4 MiB session = requests.Session() 18 24.1 MiB 0.0 MiB print 'Starting...' 19 215.1 MiB 191.0 MiB multi_get(session, 3000) 20 215.1 MiB 0.0 MiB print("Finished first round...") 21 215.1 MiB 0.0 MiB session.close() 22 215.1 MiB 0.0 MiB print 'Done.'
[2cbb7c1bbbb8] {jit-æŠèŠ
ãã¬ãŒã¹ïŒ41 0.290082
ããã¯ãšã³ãïŒ30 0.029096
åèšïŒ1612.933400
opsïŒ79116
èšé²ãããæäœïŒ23091
åŒã³åºãïŒ2567
èŠåå¡ïŒ7081
opt opsïŒ5530
ãªããã¬ãŒãïŒ1400
匷å¶åïŒ198
äžæ¢ïŒãã¬ãŒã¹ãé·ãããŸãïŒ2
äžæ¢ïŒã³ã³ãã€ã«ïŒ0
äžæ¢ïŒvableãšã¹ã±ãŒãïŒ9
ã¢ããŒãïŒãããã«ãŒãïŒ0
äžæ¢ïŒæºå ç«ã匷å¶ããïŒ0
nvirtualsïŒ9318
nvholesïŒ1113
nvreusedïŒ6666
ã«ãŒãã®ç·æ°ïŒ23
æ©ã®ç·æ°ïŒ8
解æŸãããã«ãŒãã®æ°ïŒ0
解æŸãããæ©ã®æ°ïŒ0
[2cbb7c242e8b] jit-summary}ç§ã¯ææ°ã®PyPyã䜿çšããŠä¿¡é Œã§ãã32ãããã䜿çšããŠããŸã
https://launchpad.net/~pypy/+archive/ubuntu/ppa
https://launchpad.net/%7Epypy/+archive/ubuntu/ppaâ
ãã®ã¡ãŒã«ã«çŽæ¥è¿ä¿¡ããããGitHubã§è¡šç€ºããŠãã ãã
https://github.com/kennethreitz/requests/issues/1685#issuecomment -62269627
ã
ãã°ïŒ
Line # Mem usage Increment Line Contents
================================================
16 22.0 MiB 0.0 MiB <strong i="6">@profile</strong>
17 def run():
18 22.5 MiB 0.5 MiB session = requests.Session()
19 22.5 MiB 0.0 MiB print 'Starting...'
20 217.2 MiB 194.7 MiB multi_get(session, 3000)
21 217.2 MiB 0.0 MiB print("Finished first round...")
22 217.2 MiB 0.0 MiB session.close()
23 217.2 MiB 0.0 MiB print 'Done.'
24 221.0 MiB 3.8 MiB gc.dump_rpy_heap('bench.txt')
[3fd7569b13c5] {jit-summary
Tracing: 41 0.293192
Backend: 30 0.026873
TOTAL: 1615.665337
ops: 79116
recorded ops: 23091
calls: 2567
guards: 7081
opt ops: 5530
opt guards: 1400
forcings: 198
abort: trace too long: 2
abort: compiling: 0
abort: vable escape: 9
abort: bad loop: 0
abort: force quasi-immut: 0
nvirtuals: 9318
nvholes: 1113
nvreused: 6637
Total # of loops: 23
Total # of bridges: 8
Freed # of loops: 0
Freed # of bridges: 0
[3fd756c29302] jit-summary}
ããã«ãã³ãïŒ https ïŒ
ãæéãå²ããŠããã ãããããšãããããŸãã
ãããã£ãŠãããã¯ãããã100MBã®äœ¿çšéãå ããŸãã äŒæ©ããå Žæã¯2ã€ãããŸã
ãã®ãã¡ã®1ã€ã¯ããã¹ãã¢ã¡ã¢ãªãã§GCãããŸããŸãªããšãç¶æããŠããããšã§ãã
GC以å€ã®å²ãåœãŠ-ãããã¯OpenSSLã®å
éšã®ãããªãã®ãæå³ããŸã
å²ãåœãŠã OpenSSLæ§é ãã©ããã確èªããè¯ãæ¹æ³ããããã©ããçåã«æããŸã
ãªãŒã¯ãããŠããŸãããããã§TLSã§ãã¹ããããŠãããã®ã§ããã¯ãã®å Žåãã§ããŸãã
éTLSãµã€ãã§è©ŠããŠããããåçŸããããã©ããã確èªããŸããïŒ
åå5æ38å04ç§PMã¹ã¿ãŒã¹SuÅcovã®å2014幎11æ8æ¥ã«ã¯[email protected]
æžããŸããïŒ
ãã°ïŒ
è¡çªå·ã¡ã¢ãªäœ¿çšéå¢åè¡ã®å 容
16 22.0 MiB 0.0 MiB <strong i="18">@profile</strong> 17 def run(): 18 22.5 MiB 0.5 MiB session = requests.Session() 19 22.5 MiB 0.0 MiB print 'Starting...' 20 217.2 MiB 194.7 MiB multi_get(session, 3000) 21 217.2 MiB 0.0 MiB print("Finished first round...") 22 217.2 MiB 0.0 MiB session.close() 23 217.2 MiB 0.0 MiB print 'Done.' 24 221.0 MiB 3.8 MiB gc.dump_rpy_heap('bench.txt')
[3fd7569b13c5] {jit-æŠèŠ
ãã¬ãŒã¹ïŒ41 0.293192
ããã¯ãšã³ãïŒ30 0.026873
åèšïŒ1615.665337
opsïŒ79116
èšé²ãããæäœïŒ23091
åŒã³åºãïŒ2567
èŠåå¡ïŒ7081
opt opsïŒ5530
ãªããã¬ãŒãïŒ1400
匷å¶åïŒ198
äžæ¢ïŒãã¬ãŒã¹ãé·ãããŸãïŒ2
äžæ¢ïŒã³ã³ãã€ã«ïŒ0
äžæ¢ïŒvableãšã¹ã±ãŒãïŒ9
ã¢ããŒãïŒãããã«ãŒãïŒ0
äžæ¢ïŒæºå ç«ã匷å¶ããïŒ0
nvirtualsïŒ9318
nvholesïŒ1113
nvreusedïŒ6637
ã«ãŒãã®ç·æ°ïŒ23
æ©ã®ç·æ°ïŒ8
解æŸãããã«ãŒãã®æ°ïŒ0
解æŸãããæ©ã®æ°ïŒ0
[3fd756c29302] jit-summary}ããã«ãã³ãïŒ https ïŒ
ãæéãå²ããŠããã ãããããšãããããŸãã
â
ãã®ã¡ãŒã«ã«çŽæ¥è¿ä¿¡ããããGitHubã§è¡šç€ºããŠãã ãã
https://github.com/kennethreitz/requests/issues/1685#issuecomment -62277822
ã
@alex ã
@stasã¯ããã®ãã³ãããŒã¯ã«éåžžã®httpïŒéSSL / TLSïŒæ¥ç¶ã䜿çšããŠãããš@ stasã®ãã³ãããŒã¯ã¹ã¯ãªããã䜿çšããŠãéåžžã®httpæ¥ç¶ã䜿çšããŠMacïŒOSX 10.9.5 2.5 GHz i5 8 GB 1600 MHz DDR3ïŒã§å®è¡ããŸããã
ããã圹ç«ã€å Žåã¯ããããæ¯èŒããç§ã®çµæã§ãïŒããªãã®æ瀺ã䜿çšããŠïŒïŒ
https://gist.github.com/mhjohnson/a13f6403c8c3a3d49b8d
ã©ãèããŠãããæããŠãã ããã
ããããšãã
-ããã
GitHubã®æ£èŠè¡šçŸãç·©ãããŸãã å®å šã«ä¿®æ£ããããšã¯æããªãã®ã§ããããåéããŸãã
ããã«ã¡ã¯ãå€åç§ã¯åé¡ãååšããããšãææããã®ãæäŒãããšãã§ããŸãã ãªã¯ãšã¹ãã䜿çšããã¯ããŒã©ãŒãšããã«ãããã»ãã·ã³ã°ã䜿çšããããã»ã¹ããããŸãã è€æ°ã®ã€ã³ã¹ã¿ã³ã¹ãåãçµæãåãåã£ãŠããããšãèµ·ãã£ãŠããŸãã çµæã®ãããã¡ãŸãã¯ãœã±ããèªäœã«ãªãŒã¯ãããå¯èœæ§ããããŸãã
ã³ãŒãã®ãµã³ãã«ãéä¿¡ã§ãããã©ããããŸãã¯æ å ±ã®ã©ã®éšåããå ±æããããŠããïŒãªãŒã¯ãããŠããïŒããç¹å®ããããã®åç §ããªãŒãçæããæ¹æ³ãæããŠãã ãã
ããããšã
@barrocaããã¯å¥ã®åé¡ã§ãã ã¹ã¬ããéã§ã»ãã·ã§ã³ã䜿çšãã stream=True
ã䜿çšããŠããå¯èœæ§ããããŸãã èªã¿åããå®äºããåã«å¿çãéããŠããå Žåããœã±ããã¯ãã®ããŒã¿ããŸã æ®ã£ãŠããç¶æ
ã§æ¥ç¶ããŒã«ã«æ»ãããŸãïŒç§ãæ£ããèŠããŠããå ŽåïŒã ãããèµ·ãããªãå Žåã¯ãææ°ã®æ¥ç¶ãååŸãããµãŒããŒãããã£ãã·ã¥ãããå¿çãåä¿¡ããŠââããå¯èœæ§ããããŸãã ãããã«ãããããã¯ã¡ã¢ãªãªãŒã¯ã瀺ããã®ã§ã¯ãããŸããã
@ sigmavirus24ããããšãIanãããªããèšåããããã«ãããã¯ã¹ã¬ããéã§ã®ã»ãã·ã§ã³ã®ããã€ãã®ãã¹äœ¿çšã§ããã 説æãããããšããééã£ãåé¡ãæŽæ°ããŠç³ãèš³ãããŸããã
å¿é ãããŸãã@barroca :)
ãã以äžã®èŠæ ã¯ãªããæåãå°œããããšæããŸãã åéããŠãå¿ èŠã«å¿ããŠå調æ»ãããŠããã ããŸãã
ããã§ããã®åé¡ã®è§£æ±ºçã¯äœã§ããïŒ
@Makecodeeasyç§ãç¥ããã
ãããŸã§ã®ãšããã requests
ã«é¢ããç§ã®åé¡ã¯ãã¹ã¬ããã»ãŒãã§ã¯ãªããšããããšã§ãã
ã¹ã¬ããããšã«å¥ã
ã®ã»ãã·ã§ã³ã䜿çšããã®ãæé©ã§ãã
ãã£ãã·ã¥å¿çãæ€èšŒããããã«äœçŸäžãã®URLããŠã©ãŒã¯ã¹ã«ãŒããããã®é²è¡äžã®äœæ¥ã¯ãç§ãããã«å°ããŸã
requests
ãThreadPoolExecutor
ãŸãã¯threading
ãšçžäºäœçšãããšãã¡ã¢ãªäœ¿çšéãåççãè¶
ããŠå¢å ããããšãããããŸããã
çµå±ãç§ã¯multiprocessing.Process
ã䜿çšããŠã¯ãŒã«ãŒãåé¢ããã¯ãŒã«ãŒããšã«ç¬ç«ããã»ãã·ã§ã³ãäœæããŸã
@AndCycleãªããããªãã®åé¡ã¯ããã«ã¯ãããŸããã ãã®ç¹å®ã®ã¡ã¢ãªãªãŒã¯ã®ã±ãŒã¹ãä¿®æ£ããããã«ããŒãžãããPRããããŸããã ããã®åšãã«ãã¹ããããã®ã§ãããã¯åŸéããŠããŸããã ãããŠãããªãã®åé¡ã¯å®å šã«ç°ãªã£ãŠããããã«èãããŸãã
æãåèã«ãªãã³ã¡ã³ã
ãã以äžã®èŠæ ã¯ãªããæåãå°œããããšæããŸãã åéããŠãå¿ èŠã«å¿ããŠå調æ»ãããŠããã ããŸãã