https://github.com/alex/http-client-bench μλ λ΄κ° μ¬μ©ν λ²€μΉλ§ν¬κ° ν¬ν¨λμ΄ μμ΅λλ€.
κ²°κ³Όλ λ€μκ³Ό κ°μ΅λλ€.
| | μμ²/http | μμΌ |
| --- | --- | --- |
| CPython | 12MB/s | 200MB/s |
| νμ΄νμ΄ | 80MB/s | 300MB/s |
| μ΄λ | 150MB/s | ν΄λΉ μμ |
μμ²μ νΉν CPythonμμ μμΌμ λΉν΄ μλΉν μ€λ²ν€λλ₯Ό λΆκ³Όν©λλ€.
μ€λ²ν€λκ° μμμΈλ‘ ν½λλ€. κ·Έλ¬λ κ·Έκ²μ νΌνλ κ²μ κΉλ€λ‘μΈ μ μμ΅λλ€.
ν° λ¬Έμ λ μ°λ¦¬κ° μ²ν¬λΉ κ½€ λ§μ μ²λ¦¬λ₯Ό νλ€λ κ²μ λλ€. μ΄κ²μ΄ μ€νμ λͺ¨λ κ²μ λλ€: requests, urllib3 λ° httplib. λκ° λΉν¨μ¨μ±μ μ λ°νλμ§ μμλ΄κΈ° μν΄ μκ°μ μ΄λμ μλΉνλμ§ λ³΄λ κ²μ λ§€μ° ν₯λ―Έλ‘μΈ κ²μ λλ€.
λ€μ λ¨κ³λ httplib / urllib3μ νλ‘νμΌλ§νμ¬
κ±°κΈ° μ±λ₯?
μΌλΉ λ²ν¬
μ ν: 925.271.7005 | 20λ°λ¦¬μ΄.com
2014λ
12μ 4μΌ λͺ©μμΌ μ€ν 5:01 Cory Benfield μλ¦Ό @github.com
μΌλ€:
μ€λ²ν€λκ° μμμΈλ‘ ν½λλ€. κ·Έλ¬λ κ·Έκ²μ νΌνλ κ²μ κΉλ€λ‘μΈ μ μμ΅λλ€.
ν° λ¬Έμ λ μ°λ¦¬κ° μ²ν¬λΉ κ½€ λ§μ μ²λ¦¬λ₯Ό νλ€λ κ²μ λλ€. 그건
μ€ν μλλ‘: requests, urllib3 λ° httplib. κ·Έκ²μ
λκ° μκ°μ μλΉνλμ§ νμΈνλ κ²μ λ§€μ° ν₯λ―Έ λ‘μ΅λλ€.
λΉν¨μ¨μ μ΄λνκ³ μμ΅λλ€.β
μ΄ μ΄λ©μΌμ μ§μ λ΅μ₯νκ±°λ GitHubμμ νμΈνμΈμ.
https://github.com/kennethreitz/requests/issues/2371#issuecomment -65732050
.
urllib3μΌλ‘ λ²€μΉλ§ν¬λ₯Ό μ€ννμ΅λλ€.
νμ΄νμ΄: 120MB/s
CPython: 70MB/s
κ·Έλ¦¬κ³ CPython + μμ²μ λ€μ μ€ννμ΅λλ€. 35MB/s
(λ΄ κΈ°κ³λ λ²€μΉλ§ν¬μμ μ½κ°μ μμμ κ²½ννλ κ² κ°μ΅λλ€. λκ΅°κ°κ° λ μ‘°μ©ν μμ€ν μ κ°μ§κ³ μλ€λ©΄ κ΅μ₯ν κ²μ λλ€.)
λλ λ€λ₯Έ λͺ¨λ κ²μ μ’
λ£ ν ν λ΄ μ»΄ν¨ν°μμ μ΄κ²μ μ€ννλ €κ³ μλνμ΅λλ€.
μμ© νλ‘κ·Έλ¨ λ° ν°λ―Έλ μ°½κ³Ό μλΉν μμ μμμ΄ λ°μνμ΅λλ€.
μμΌ λ²€μΉλ§ν¬λ 30mb/sμμ 460mb/s μ¬μ΄μμ΅λλ€.
μΌλΉ λ²ν¬
μ ν: 925.271.7005 | 20λ°λ¦¬μ΄.com
2014λ
12μ 4μΌ λͺ©μμΌ μ€ν 9μ 24λΆ, Alex Gaynor [email protected]
μΌλ€:
urllib3μΌλ‘ λ²€μΉλ§ν¬λ₯Ό μ€ννμ΅λλ€.
νμ΄νμ΄: 120MB/s
CPython: 70MB/sκ·Έλ¦¬κ³ CPython + μμ²μ λ€μ μ€ννμ΅λλ€. 35MB/s
(λ΄ μ»΄ν¨ν°λ λ²€μΉλ§ν¬μμ μ½κ°μ μμμ΄ λ°μνλ κ² κ°μ΅λλ€.
λꡬλ μ§ μ¬μ©ν μ μλ λ μ‘°μ©ν μμ€ν μ κ°μ§κ³ μμ΅λλ€.β
μ΄ μ΄λ©μΌμ μ§μ λ΅μ₯νκ±°λ GitHubμμ νμΈνμΈμ.
https://github.com/kennethreitz/requests/issues/2371#issuecomment -65748982
.
μ΄μ λ²€μΉλ§ν¬λ₯Ό λ μ½κ² μ€νν μ μμΌλ―λ‘ λ€λ₯Έ μ¬λλ€μ΄ λ΄ μμΉλ₯Ό νμΈν μ μμ΅λλ€.
CPython:
BENCH SOCKET:
8GiB 0:00:22 [ 360MiB/s] [======================================================>] 100%
BENCH HTTPLIB:
8GiB 0:02:34 [53.1MiB/s] [======================================================>] 100%
BENCH URLLIB3:
8GiB 0:01:30 [90.2MiB/s] [======================================================>] 100%
BENCH REQUESTS
8GiB 0:01:30 [90.7MiB/s] [======================================================>] 100%
BENCH GO HTTP
8GiB 0:00:26 [ 305MiB/s] [======================================================>] 100%
νμ΄νμ΄:
BENCH SOCKET:
8GiB 0:00:22 [ 357MiB/s] [======================================================>] 100%
BENCH HTTPLIB:
8GiB 0:00:43 [ 189MiB/s] [======================================================>] 100%
BENCH URLLIB3:
8GiB 0:01:07 [ 121MiB/s] [======================================================>] 100%
BENCH REQUESTS
8GiB 0:01:09 [ 117MiB/s] [======================================================>] 100%
BENCH GO HTTP
8GiB 0:00:26 [ 307MiB/s] [======================================================>] 100%
μ΄...μ«μκ° μ΄μνλ€μ. λ λΌμ΄λΈλ¬λ¦¬κ° λͺ¨λ httplibλ₯Ό μ¬μ©νλλΌλ CPythonμ httplibλ μμ² λλ urllib3λ³΄λ€ λ립λλ€. κ·Έκ²μ μ³μ μ μμ΅λλ€.
κ·Έλ€μ λλ₯Ό μν΄ μΌκ΄λκ² μ¬μμ°ν©λλ€. λ²€μΉλ§ν¬λ₯Ό μλνκ³
μ¬νν μ μμ΅λκΉ? λΉμ μ΄ ν μ μλ€κ³ κ°μ νκ³ , λΉμ μ μ΄λ€ λ¬Έμ κ°
λ²€μΉλ§ν¬?
2014λ
12μ 5μΌ κΈμμΌ μ€μ 11:16:45 Cory Benfield [email protected]
μΌλ€:
μ΄...μ«μκ° μ΄μνλ€μ. CPythonμ httplibλ μμ²λ³΄λ€ λ리거λ
λ λΌμ΄λΈλ¬λ¦¬κ° λͺ¨λ httplibλ₯Ό μ¬μ©νλλΌλ urllib3? κ·Έκ²μ μ³μ μ μμ΅λλ€.β
μ΄ μ΄λ©μΌμ μ§μ λ΅μ₯νκ±°λ GitHubμμ νμΈνμΈμ.
https://github.com/kennethreitz/requests/issues/2371#issuecomment -65821989
.
λλ μ§κΈ μλ €μ§ μ‘°μ©ν κΈ°κ³λ₯Ό μ‘κ³ μμ΅λλ€. μ€μΉν΄μΌ νλ 물리μ μμμ΄κΈ° λλ¬Έμ μ¬μ©ν μ μκ² λλ λ° λͺ λΆμ΄ 걸립λλ€(λ§μμ¬ MAASλ₯Ό μ¬λν©λλ€).
CPython 2.7.8
BENCH SOCKET:
8GiB 0:00:26 [ 309MiB/s] [================================>] 100%
BENCH HTTPLIB:
8GiB 0:02:24 [56.5MiB/s] [================================>] 100%
BENCH URLLIB3:
8GiB 0:01:42 [79.7MiB/s] [================================>] 100%
BENCH REQUESTS
8GiB 0:01:45 [77.9MiB/s] [================================>] 100%
BENCH GO HTTP
8GiB 0:00:27 [ 297MiB/s] [================================>] 100%
κ°μΉ μλ μΌ:
μ΄λ² ν¨μΉ , CPython 3.4.2
:
BENCH SOCKET:
8GiB 0:00:27 [ 302MiB/s] [================================>] 100%
BENCH HTTPLIB:
8GiB 0:00:53 [ 151MiB/s] [================================>] 100%
BENCH URLLIB3:
8GiB 0:00:54 [ 149MiB/s] [================================>] 100%
BENCH REQUESTS
8GiB 0:00:56 [ 144MiB/s] [================================>] 100%
BENCH GO HTTP
8GiB 0:00:31 [ 256MiB/s] [================================>] 100%
λ€μμ μ¬μ©νμ¬ Python2μμ λμΌν ν¨κ³Όλ₯Ό μ»μ μ μμ΄μΌ ν©λλ€.
env PYTHONUNBUFFERED=
λλ -u
νλκ·Έ.
2014λ
12μ 5μΌ κΈμμΌ μ€μ 11:42:36 Corey Farwell [email protected]
μΌλ€:
κ°μΉ μλ μΌ:
μ΄ ν¨μΉ https://gist.github.com/frewsxcv/1c0f3c81cda508e1bca9 , CPython
3.4.2:λ²€μΉ μμΌ:
8GiB 0:00:27 [ 302MiB/s] [================================>] 100%
λ²€μΉ HTTPLIB:
8GiB 0:00:53 [ 151MiB/s] [================================>] 100%
λ²€μΉ URLLIB3:
8GiB 0:00:54 [ 149MiB/s] [================================>] 100%
λ²€μΉ μμ²
8GiB 0:00:56 [ 144MiB/s] [================================>] 100%
λ²€μΉ GO HTTP
8GiB 0:00:31 [ 256MiB/s] [================================>] 100%β
μ΄ μ΄λ©μΌμ μ§μ λ΅μ₯νκ±°λ GitHubμμ νμΈνμΈμ.
https://github.com/kennethreitz/requests/issues/2371#issuecomment -65826239
.
@alex ν₯λ―Έλ‘κ²λ env PYTHONUNBUFFERED=
λλ -u
λ Python 2μμ λμΌν ν¨κ³Όλ₯Ό λνλ΄μ§ μμ΅λλ€. λ΄ μ»΄ν¨ν°μμ λ€μ΄μ€λ κ²°κ³Όμ
λλ€.
μ’μ΅λλ€. μλ λ°μ΄ν°λ μ΄ ν
μ€νΈλ₯Ό μ€ννλ κ² μΈμλ μ무 κ²λ νμ§ μλ μμ€ν
μμ κ°μ Έμ¨ κ²μ
λλ€. λ§μ§λ§ ν
μ€νΈλ Python -u
νλκ·Έκ° μ€μ λ μνμμ μ€νλμμΌλ©° μ΄ νλκ·Έλ ν¨κ³Όκ° μμμ μ μ μμ΅λλ€.
Python 2.7.6
go version go1.2.1 linux/amd64
BENCH SOCKET:
8GiB 0:00:16 [ 500MiB/s] [================================>] 100%
BENCH HTTPLIB:
8GiB 0:01:32 [88.6MiB/s] [================================>] 100%
BENCH URLLIB3:
8GiB 0:01:20 [ 101MiB/s] [================================>] 100%
BENCH REQUESTS
8GiB 0:01:21 [ 100MiB/s] [================================>] 100%
BENCH GO HTTP
8GiB 0:00:21 [ 385MiB/s] [================================>] 100%
Python 2.7.6
go version go1.2.1 linux/amd64
BENCH SOCKET:
8GiB 0:00:16 [ 503MiB/s] [================================>] 100%
BENCH HTTPLIB:
8GiB 0:01:33 [87.8MiB/s] [================================>] 100%
BENCH URLLIB3:
8GiB 0:01:20 [ 101MiB/s] [================================>] 100%
BENCH REQUESTS
8GiB 0:01:22 [99.3MiB/s] [================================>] 100%
BENCH GO HTTP
8GiB 0:00:20 [ 391MiB/s] [================================>] 100%
Python 2.7.6
go version go1.2.1 linux/amd64
BENCH SOCKET:
8GiB 0:00:16 [ 506MiB/s] [================================>] 100%
BENCH HTTPLIB:
8GiB 0:01:31 [89.1MiB/s] [================================>] 100%
BENCH URLLIB3:
8GiB 0:01:20 [ 101MiB/s] [================================>] 100%
BENCH REQUESTS
8GiB 0:01:20 [ 101MiB/s] [================================>] 100%
BENCH GO HTTP
8GiB 0:00:21 [ 389MiB/s] [================================>] 100%
μ΄ μμΉλ λ§€μ° μμ μ μ΄λ©° λ€μκ³Ό κ°μ κΈ°λ₯μ 보μ¬μ€λλ€.
FWIW, λ°©κΈ @kevinburke μμ buffering=True
λ₯Ό μΆκ°νμ¬ λ³ν©νμ΅λλ€. μ€ννμΈμ.
κ·Έκ²μ ν¬ν¨?
2014λ
12μ 5μΌ κΈμμΌ μ€ν 12:04:40 Cory Benfield [email protected]
μΌλ€:
μ’μ, μλ λ°μ΄ν°λ λ€λ₯Έ μμ μ μννμ§ μλ κΈ°κ³μμ κ°μ Έμ¨ κ²μ λλ€.
νμ§λ§ μ΄λ¬ν ν μ€νΈλ₯Ό μ€νν©λλ€. λ§μ§λ§ ν μ€νΈλ Python -u νλκ·Έλ‘ μ€νλμμ΅λλ€.
μ€μ νκ³ νλκ·Έκ° μν₯μ λ―ΈμΉμ§ μλ κ²μ λ³Ό μ μμ΅λλ€.νμ΄μ¬ 2.7.6
go λ²μ go1.2.1 linux/amd64λ‘ μ΄λ
λ²€μΉ μμΌ:
8GiB 0:00:16 [ 500MiB/s] [================================>] 100%
λ²€μΉ HTTPLIB:
8GiB 0:01:32 [88.6MiB/s] [================================>] 100%
λ²€μΉ URLLIB3:
8GiB 0:01:20 [ 101MiB/s] [================================>] 100%
λ²€μΉ μμ²
8GiB 0:01:21 [ 100MiB/s] [=================================>] 100%
λ²€μΉ GO HTTP
8GiB 0:00:21 [ 385MiB/s] [================================>] 100%νμ΄μ¬ 2.7.6
go λ²μ go1.2.1 linux/amd64λ‘ μ΄λ
λ²€μΉ μμΌ:
8GiB 0:00:16 [ 503MiB/s] [===============================>] 100%
λ²€μΉ HTTPLIB:
8GiB 0:01:33 [87.8MiB/s] [================================>] 100%
λ²€μΉ URLLIB3:
8GiB 0:01:20 [ 101MiB/s] [================================>] 100%
λ²€μΉ μμ²
8GiB 0:01:22 [99.3MiB/s] [================================>] 100%
λ²€μΉ GO HTTP
8GiB 0:00:20 [ 391MiB/s] [================================>] 100%νμ΄μ¬ 2.7.6
go λ²μ go1.2.1 linux/amd64λ‘ μ΄λ
λ²€μΉ μμΌ:
8GiB 0:00:16 [ 506MiB/s] [================================>] 100%
λ²€μΉ HTTPLIB:
8GiB 0:01:31 [89.1MiB/s] [================================>] 100%
λ²€μΉ URLLIB3:
8GiB 0:01:20 [ 101MiB/s] [================================>] 100%
λ²€μΉ μμ²
8GiB 0:01:20 [ 101MiB/s] [================================>] 100%
λ²€μΉ GO HTTP
8GiB 0:00:21 [ 389MiB/s] [================================>] 100%μ΄ μμΉλ λ§€μ° μμ μ μ΄λ©° λ€μκ³Ό κ°μ κΈ°λ₯μ 보μ¬μ€λλ€.
- μμ μμΌ μ½κΈ°λ λΉ λ¦ λλ€.
- Goλ μμ μμΌ μ½κΈ° μλμ μ½ 80%μ λλ€.
- urllib3μ μμ μμΌ μ½κΈ° μλμ μ½ 20%μ λλ€.
- μμ²μ urllib3λ³΄λ€ μ½κ° λ립λλ€.
λ°μ΄ν°κ° ν΅κ³Όν λͺ κ°μ μ€ν νλ μμ μΆκ°ν©λλ€.- httplibλ requests/urllib3λ³΄λ€ λ립λλ€. κ·Έκ²μ λ¨μ§ λΆκ°λ₯ν©λλ€,
httplib λλ μμΌ λΌμ΄λΈλ¬λ¦¬λ₯Ό
httplibκ° μλ λ°©λ².β
μ΄ μ΄λ©μΌμ μ§μ λ΅μ₯νκ±°λ GitHubμμ νμΈνμΈμ.
https://github.com/kennethreitz/requests/issues/2371#issuecomment -65829335
.
Cory - μ μμ μΌλ μ΅μ λ²μ μ λ²€μΉ ν΄λΌμ΄μΈνΈ 보기
buffering=True in httplib(requests/urllib3 μ²λΌ)
μΌλΉ λ²ν¬
μ ν: 925.271.7005 | 20λ°λ¦¬μ΄.com
2014λ
12μ 5μΌ κΈμμΌ μ€μ 10:04 Cory Benfield μλ¦Ό @github.com
μΌλ€:
μ’μ, μλ λ°μ΄ν°λ λ€λ₯Έ μμ μ μννμ§ μλ κΈ°κ³μμ κ°μ Έμ¨ κ²μ λλ€.
νμ§λ§ μ΄λ¬ν ν μ€νΈλ₯Ό μ€νν©λλ€. λ§μ§λ§ ν μ€νΈλ Python -u νλκ·Έλ‘ μ€νλμμ΅λλ€.
μ€μ νκ³ νλκ·Έκ° μν₯μ λ―ΈμΉμ§ μλ κ²μ λ³Ό μ μμ΅λλ€.νμ΄μ¬ 2.7.6
go λ²μ go1.2.1 linux/amd64λ‘ μ΄λ
λ²€μΉ μμΌ:
8GiB 0:00:16 [ 500MiB/s] [================================>] 100%
λ²€μΉ HTTPLIB:
8GiB 0:01:32 [88.6MiB/s] [================================>] 100%
λ²€μΉ URLLIB3:
8GiB 0:01:20 [ 101MiB/s] [================================>] 100%
λ²€μΉ μμ²
8GiB 0:01:21 [ 100MiB/s] [=================================>] 100%
λ²€μΉ GO HTTP
8GiB 0:00:21 [ 385MiB/s] [================================>] 100%νμ΄μ¬ 2.7.6
go λ²μ go1.2.1 linux/amd64λ‘ μ΄λ
λ²€μΉ μμΌ:
8GiB 0:00:16 [ 503MiB/s] [===============================>] 100%
λ²€μΉ HTTPLIB:
8GiB 0:01:33 [87.8MiB/s] [================================>] 100%
λ²€μΉ URLLIB3:
8GiB 0:01:20 [ 101MiB/s] [================================>] 100%
λ²€μΉ μμ²
8GiB 0:01:22 [99.3MiB/s] [================================>] 100%
λ²€μΉ GO HTTP
8GiB 0:00:20 [ 391MiB/s] [================================>] 100%νμ΄μ¬ 2.7.6
go λ²μ go1.2.1 linux/amd64λ‘ μ΄λ
λ²€μΉ μμΌ:
8GiB 0:00:16 [ 506MiB/s] [================================>] 100%
λ²€μΉ HTTPLIB:
8GiB 0:01:31 [89.1MiB/s] [================================>] 100%
λ²€μΉ URLLIB3:
8GiB 0:01:20 [ 101MiB/s] [================================>] 100%
λ²€μΉ μμ²
8GiB 0:01:20 [ 101MiB/s] [================================>] 100%
λ²€μΉ GO HTTP
8GiB 0:00:21 [ 389MiB/s] [================================>] 100%μ΄ μμΉλ λ§€μ° μμ μ μ΄λ©° λ€μκ³Ό κ°μ κΈ°λ₯μ 보μ¬μ€λλ€.
- μμ μμΌ μ½κΈ°λ λΉ λ¦ λλ€.
- Goλ μμ μμΌ μ½κΈ° μλμ μ½ 80%μ λλ€.
- urllib3μ μμ μμΌ μ½κΈ° μλμ μ½ 20%μ λλ€.
- μμ²μ urllib3λ³΄λ€ μ½κ° λ립λλ€.
λ°μ΄ν°κ° ν΅κ³Όν λͺ κ°μ μ€ν νλ μμ μΆκ°ν©λλ€.- httplibλ requests/urllib3λ³΄λ€ λ립λλ€. κ·Έκ²μ λ¨μ§ λΆκ°λ₯ν©λλ€,
httplib λλ μμΌ λΌμ΄λΈλ¬λ¦¬λ₯Ό
httplibκ° μλ λ°©λ².β
μ΄ μ΄λ©μΌμ μ§μ λ΅μ₯νκ±°λ GitHubμμ νμΈνμΈμ.
https://github.com/kennethreitz/requests/issues/2371#issuecomment -65829335
.
μ, ν¨μ¬ λ μ΄ν΄νκΈ° μν΄ httplibμ μ±λ₯ λμμ μμ ν©λλ€.
μλ‘μ΄ κ²°κ³Ό λ° κ²°λ‘ :
Python 2.7.6
go version go1.2.1 linux/amd64
BENCH SOCKET:
8GiB 0:00:16 [ 499MiB/s] [================================>] 100%
BENCH HTTPLIB:
8GiB 0:01:12 [ 113MiB/s] [================================>] 100%
BENCH URLLIB3:
8GiB 0:01:21 [ 100MiB/s] [================================>] 100%
BENCH REQUESTS
8GiB 0:01:20 [ 101MiB/s] [================================>] 100%
BENCH GO HTTP
8GiB 0:00:20 [ 391MiB/s] [================================>] 100%
λ°λΌμ μ¬κΈ°μμ μ€μ λΉμ©μ νλ¦Όμμ΄ httplibμ λλ€. μλλ₯Ό λμ΄λ €λ©΄ httplibλ₯Ό μ κ±°ν΄μΌ ν©λλ€.
λλ httplibμ μ΄λ€ λΆλΆμ΄ μ°λ¦¬μκ² λΉμ©μ λ°μμν€λμ§ μμλ΄κ³ μΆμ΅λλ€. bench_httplib.py
νλ‘νμΌλ§νλ κ²μ΄ μ’μ λ€μ λ¨κ³λΌκ³ μκ°ν©λλ€.
bench_socket.py
ν
μ€νΈμ ν΄λΉ μ€μ μΆκ°νμ¬ socket.makefile
λ₯Ό ν΅ν΄ μμΌμ νμΌ κ°μ²΄λ‘ λ³ννλ κ²μ λ°°μ νμ§λ§ μ ν μλκ° λλ €μ§μ§ μμμ΅λλ€. μ΄μνκ²λ μλκ° λΉ¨λΌμ§λ κ² κ°μ΅λλ€.
λλ΅μ κ±°μ νμ€νκ² μ μ‘ μΈμ½λ©: μ²ν¬ μ²λ¦¬μ
λλ€.
μ°Έμ‘°: https://github.com/alex/http-client-bench/pull/6 , μ ν
μλ²μ Content-Lengthλ μκΈ°μΉ μμ κ²°κ³Όλ₯Ό μμ±ν©λλ€.
2014λ
12μ 5μΌ κΈμμΌ μ€ν 12:24:53 Cory Benfield [email protected]
μΌλ€:
λ°λΌμ μ¬κΈ°μμ μ€μ λΉμ©μ νλ¦Όμμ΄ httplibμ λλ€. μ΄λ₯Ό κ°μννλ €λ©΄ λ€μμ΄ νμν©λλ€.
httplibλ₯Ό λ°©ν΄νμ§ μλλ‘ ν©λλ€.λλ httplibμ μ΄λ€ λΆλΆμ΄ μ°λ¦¬μκ² λΉμ©μ λ°μμν€λμ§ μμλ΄κ³ μΆμ΅λλ€. NS
bench_httplib.pyλ₯Ό νλ‘νμΌλ§νλ κ²μ΄ μ’μ λ€μ λ¨κ³λΌκ³ μκ°νμμμ€.β
μ΄ μ΄λ©μΌμ μ§μ λ΅μ₯νκ±°λ GitHubμμ νμΈνμΈμ.
https://github.com/kennethreitz/requests/issues/2371#issuecomment -65831653
.
ν₯λ―Έλ‘μ΄.
μ²ν¬ μ²λ¦¬λ κ±°μ νμ€ν λ¬Έμ μ΄λ©°, νΉν μ²ν¬κ° goμ κΈ°λ³Έ HTTP λͺ¨λμ΄κΈ° λλ¬Έμ goκ° λ μ μ²λ¦¬νλ€λ μ¬μ€μ κ·Έλ€μ§ λλμ§ μμ΅λλ€.
κ·Έλ¬λ μμ μμΌλ³΄λ€ λΉ λ₯Έ μμ²μ...μκΈ°μΉ μμ΅λλ€!
μ£Όλͺ©ν κ°μΉκ° μλ ν κ°μ§: μμΌμ΄ μ΄μ ν μ€νΈμμ μ²ν¬ μΈμ½λ©μ λμ½λ©νμ§ μμλ€λ©΄ μ€μ λ‘ λ€λ₯Έ λ°©λ²λ³΄λ€ λ μ μ λ°μ΄ν°λ₯Ό μ½κΈ° λλ¬Έμ λΆκ³΅μ ν μ΄μ μ μ»μμ΅λλ€! κ·Έλ€μ λͺ¨λ μ²ν¬ ν€λμ 8GBμ λ°μ΄ν°λ₯Ό μ½κ³ μμμ΅λλ€.
μ΄κ²μ νμ μ§λ¬ΈμΌλ‘ μ΄μ΄μ§λλ€. μ°λ¦¬λ μ¬μ ν μ΄λ¬ν λͺ¨λ λ°©λ²μ΄ μ€μ λ‘ λμΌν μμ λ°μ΄ν°λ₯Ό μ½κ³ μλ€κ³ μκ°ν©λκΉ?
μ, μμΌ λ μ΄μ΄κ° λΆμ νμλ₯Ό νκ³ μ²ν¬λ λ©νλ°μ΄ν°λ₯Ό λμ½λ©νμ§ μμμ΅λλ€.
κΈ°μ μ μΌλ‘ μ‘°κΈ λ μ½μ΅λλ€. κ·Έκ²μ "μΌλ§λ 빨리
μ°λ¦¬κ° μ½μ μ μμ΅λκΉ?", μ무κ²λ μ¦λͺ
νμ§ λ§μμμ€.
2014λ
12μ 5μΌ κΈμμΌ μ€ν 12:33:10 Cory Benfield [email protected]
μΌλ€:
ν₯λ―Έλ‘μ΄.
μ²ν¬ μ²λ¦¬λ κ±°μ νμ€ν λ¬Έμ μ΄λ©° λλ μ€μ λ‘
νΉν μ²ν¬κ° κΈ°λ³Έκ°μ΄λ―λ‘ goκ° λ μ μ²λ¦¬νλ€λ μ¬μ€μ λλμ΅λλ€.
μ΄λμ μν HTTP λͺ¨λ.κ·Έλ¬λ μμ μμΌλ³΄λ€ λΉ λ₯Έ μμ²μ...μκΈ°μΉ μμ΅λλ€!
μ£Όλͺ©ν κ°μΉκ° μλ ν κ°μ§: μμΌμ΄ μ²ν¬ μΈμ½λ©μ λμ½λ©νμ§ μλ κ²½μ°
μ΄μ ν μ€νΈμμ μ€μ λ‘λ λΆκ³΅μ ν μ΄μ μ μ»μμ΅λλ€.
λ€λ₯Έ λ°©λ²λ³΄λ€ μ μ λ°μ΄ν°λ₯Ό μ½μ΅λλ€! κ·Έλ€μ λͺ¨λ μ½κ³ μμλ€
μ²ν¬ ν€λμ 8GB λ°μ΄ν°.μ΄κ²μ νμ μ§λ¬ΈμΌλ‘ μ΄μ΄μ§λλ€. μ°λ¦¬λ μ¬μ ν μ΄λ¬ν λͺ¨λ λ°©λ²μ μκ°ν©λκΉ?
μ€μ λ‘ κ°μ μμ λ°μ΄ν°λ₯Ό μ½κ³ μμ΅λκΉ?β
μ΄ μ΄λ©μΌμ μ§μ λ΅μ₯νκ±°λ GitHubμμ νμΈνμΈμ.
https://github.com/kennethreitz/requests/issues/2371#issuecomment -65833299
.
μ΄κ²μ΄ μ°λ¦¬κ° ν λ²μ μμΌμμ μ½λ μ²ν¬ ν¬κΈ°μ κ΄λ ¨μ΄ μλ€κ³ ν΄λ λλΌμ§ μμ κ²μ λλ€.
λμμ΄ λ§μ΄ λ @alexλ₯Ό μν μΌμ΄ν¬ :cake:
@nelhage λ λ€μν μμ λ₯Ό μΆμ νμ΅λλ€(μ μ‘μμ
μΈμ½λ©: μ²ν¬ μΌμ΄μ€) https://gist.github.com/nelhage/dd6490fbc5cfb815f762
κ²°κ³Όμ
λλ€. httplibμ λ²κ·Έκ° μλ κ² κ°μ΅λλ€.
νμ μμΌμμ μ 체 μ²ν¬λ₯Ό μ½λ κ²μ μλλλ€.
2014λ
12μ 8μΌ μμμΌ μ€μ 9:05:14 Kenneth Reitz [email protected]
μΌλ€:
@alexλ₯Ό μν μΌμ΄ν¬ https://github.com/alex λ§€μ° λμμ΄ λμμ΅λλ€ [μ΄λ―Έμ§:
:μΌμ΄ν¬:]β
μ΄ μ΄λ©μΌμ μ§μ λ΅μ₯νκ±°λ GitHubμμ νμΈνμΈμ.
https://github.com/kennethreitz/requests/issues/2371#issuecomment -66147998
.
κ·Έλμ μ°λ¦¬κ° μ¬κΈ°μ μλ κ²μ μ무λ μ€μ λ‘ μ μ§ κ΄λ¦¬νμ§ μλ νμ€ λΌμ΄λΈλ¬λ¦¬μ λ²κ·Έμ λκΉ? ( @Lukasa μλ 1λ μ΄μ μ΄λ¦° ν¨μΉ μΈνΈκ° 2κ° μ΄μ μμ΅λλ€.) μ€λ λ°€ μ΄λκ°μμ λͺ©λ‘μ μ μ·¨λ₯Ό μ¬λ¦΄ μλ μμ΅λλ€.
λκ΅°κ° (λλ κ·Έκ²μ μ»μ μ μμ΅λλ€, λΆλΆλͺ
) μλ§λ pdbλ‘ λ릴 λ€μ΄ν΄μΌ ν κ²μ
λλ€
λλ 무μΈκ°λ₯Ό λ§λ€κ³ μ νν μ½λκ° 20λ°μ΄νΈλ₯Ό μμ±νλμ§ μμλ΄μμμ€.
μ’μ λ²κ·Έ λ³΄κ³ μλ₯Ό μμ±ν μ μλλ‘ μ½μ΅λλ€.
2014λ
12μ 8μΌ μμμΌ μ€μ 9:14:09 Ian Cordasco [email protected]
μΌλ€:
κ·Έλμ μ°λ¦¬κ° μ¬κΈ°μ μλ κ²μ νμ€ λΌμ΄λΈλ¬λ¦¬μ λ²κ·Έμ λλ€.
μ μ§? ( @Lukasa https://github.com/Lukasa μλ μ΅μ 2κ°μ ν¨μΉκ° μμ΅λλ€.
1λ μ΄μ μ΄λ¦° μΈνΈ
μ€λ λ°€ μ΄λκ°β
μ΄ μ΄λ©μΌμ μ§μ λ΅μ₯νκ±°λ GitHubμμ νμΈνμΈμ.
https://github.com/kennethreitz/requests/issues/2371#issuecomment -66149522
.
μ€λ λ°€μ΄λ λ΄μΌ μ무λ μ μ€λ©΄ λ§μΆλλ‘ λ Έλ ₯νκ² μ΅λλ€.
κ·Όλ³Έ μμΈμ λν μμμ΄ μμ΅λκΉ? μ΄ μ§§μ μ½κΈ°λ₯Ό μμ±νλ κ²μ 무μμ΄λ©°, κ·Έκ²λ€μ΄ μμΌλ©΄ μν©μ΄ μΌλ§λ κ°μ λ©λκΉ?
@kislyuk λ΄κ° μλ ν
@λ£¨μΉ΄μ¬ κ°μ¬ν©λλ€. urllib3/requestsλ₯Ό μ¬μ©νλ μ²ν¬ μλ΅μ λ€μ΄λ‘λ μλκ° curl λ° κΈ°ν λΌμ΄λΈλ¬λ¦¬λ³΄λ€ ν¨μ¬ λλ¦° μ±λ₯ λ¬Έμ λ₯Ό λ€λ£¨κ³ μμΌλ©° μ΄κ²μ΄ λ²μΈμΈμ§ μ΄ν΄νλ €κ³ ν©λλ€.
μ΄κ±Έλ‘ μ‘°κΈ μ°λ μ΅λλ€. 짧μ μ½κΈ°λ httplibμ _read_chunked ν¨μμμ κ°μ Έμ΅λλ€.
https://fossies.org/linux/misc/Python-2.7.9.tgz/Python-2.7.9/Lib/httplib.py#l_585
2λ°μ΄νΈ μ½κΈ°λ μ£Όλ‘ λΌμΈ 622μμ λ°μνλ κ²μΌλ‘ 보μ λλ€.
μ΄μ μ κ²μν κ²κ³Ό μ½κ° λ€λ₯Έ strace ν¨ν΄μ μ»μμ΅λλ€.
recvfrom(3, "400\r\n\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\0\0\0"..., 8192, 0, NULL, NULL) = 8192
recvfrom(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 0\0\0\0\0\0\0\0\0\0"..., 54, 0, NULL, NULL) = 54
recvfrom(3, "\r\n", 2, 0, NULL, NULL) = 2
μ΄ ν¨ν΄μ λ€μκ³Ό κ°μ΄ μ€λͺ ν μ μμ΅λλ€.
κ·Έλ° λ€μ ν¨ν΄μ΄ λ°λ³΅λ©λλ€(1λ¨κ³λ‘ λμκ°κΈ°).
FWIW, λλ 2λ°μ΄νΈ μ²ν¬ μ’ κ²°μ μ½κΈ°λ₯Ό μ²ν¬ λ³Έλ¬Έ μ½κΈ°λ‘ λ‘€λ§νμ¬ μ¬κΈ°μμ μ λΉν(20% μ λ) μλ ν₯μμ λ§λ€ μ μμμ λ°κ²¬νμ΅λλ€.
value.append(self._safe_read(chunk_left))
amt -= chunk_left
self._safe_read(2) # toss the CRLF at the end of the chunk
λμ λ€μμ μννμμμ€.
value.append(self._safe_read(chunk_left + 2)[:-2])
amt -= chunk_left
νμ§λ§ μ€μ λ‘λ 54λ°μ΄νΈ μ½κΈ°κ° 54λ°μ΄νΈ(μ¦, 8192λ°μ΄νΈ)λ³΄λ€ λ λ§μ λ°μ΄νΈλ₯Ό λ²νΌλ§ν μ μλ€λ©΄ λ λμ κ²μ λλ€. μ¦, 2λ°μ΄νΈ μ½κΈ°μ κ΄λ ¨νμ¬ λ²νΌλ§λ μμΌμ΄ λΉμ΄ μμ§ μμμ μλ―Έν©λλ€.
μ΄μ λνμ¬. μμ μ½κΈ°κ° μ²λ¦¬λ μμ€μ μ£Όμ μμΈμΈμ§(λλ localhostκ° μλ) νμ€νμ§ μμ΅λλ€. λλ 1031λ°μ΄νΈμ λ°°μκ° λλλ‘ μμΌ λ²νΌ ν¬κΈ°λ₯Ό κ°μ§κ³ λμκ³ straceκ° λ μ΄μ μμ μ½κΈ°λ₯Ό κ°μ§μ§ μμμλ λΆκ΅¬νκ³ μ²λ¦¬λμ ν° μν₯μ λ―ΈμΉμ§ μμμ΅λλ€.
μ²λ¦¬λ μμ€μ socket.pyκ° μμ μ½κΈ°λ₯Ό μ²λ¦¬νλ λ°©λ²κ³Ό λ κ΄λ ¨μ΄ μμ μ μλ€κ³ μκ°ν©λλ€. λ€μμ κ΄λ ¨ μ½λμ λλ€(socket.readμμ).
https://fossies.org/linux/misc/Python-2.7.9.tgz/Python-2.7.9/Lib/socket.py#l_336
socket.readμ λͺ μμ κΈΈμ΄λ₯Ό μ λ¬νκ³ κΈ°μ‘΄ λ²νΌλ§λ λ°μ΄ν°μμ μ΄λ₯Ό μνν μ μλ κ²½μ° μ½λ κ²½λ‘λ λ€μκ³Ό κ°μ΅λλ€.
buf = self._rbuf
buf.seek(0, 2) # seek end
#.....
# Read until size bytes or EOF seen, whichever comes first
buf_len = buf.tell()
if buf_len >= size:
# Already have size bytes in our buffer? Extract and return.
buf.seek(0)
rv = buf.read(size)
self._rbuf = StringIO()
self._rbuf.write(buf.read())
return rv
μ¬κΈ°μ λ΄κ° μΈμ§νλ λ¬Έμ λ 2λ°μ΄νΈ μ½κΈ°λ μ½μ§ μμ λλ¨Έμ§λ₯Ό μλ‘μ΄ StringIOλ‘ λ³΅μ¬νλ€λ κ²μ μλ―Ένλ€λ κ²μ λλ€. μ΄κ²μ λ§μ μμ μ½κΈ°μ λν΄ λ§€μ° λΉμ κ² κ°μ΅λλ€. μ£Όμ΄μ§ StringIOκ° μ½μ§ μμ λλ¨Έμ§λ₯Ό μλ‘μ΄ StringIOλ‘ λ³΅μ¬νλ νμ¬ ν¨ν΄μ΄ μλλΌ κ° μ½κΈ°μμ μ΄λ»κ²λ μμ§λ μ μλ€λ©΄ μ²λ¦¬λμ λμμ΄ λ μ μμ΅λλ€.
@gardenia μ΄ λͺ¨λ κ²μ ν‘μν κΈ°νκ° μμμ§λ§ μ¬κΈ°μμ λΉμ μ λ Έλ ₯κ³Ό μΌμ λν΄ λλ¨ν κ°μ¬ν©λλ€. @shazow μλ§λ @gardenia μ μ°κ΅¬κ° ν₯λ―Έλ‘μΈ κ²μ λλ€.
:+1: @gardenia κ°μ¬ν©λλ€. λ§λΆμ¬μ, λ΄ μ¬μ© μ¬λ‘μ μ±λ₯μ λν λ΄ μμ μ μ°κ΅¬λ λ΄ κ²½μ° μλ΅μ΄ μ²ν¬λμ§ μμμ§λ§ urllib3μ΄ μμ²λ³΄λ€ 20+% λ λΉ λ₯΄κ² μννλ―λ‘ νΉμ±ννλ €λ μ½κ°μ μ€λ²ν€λκ° λμ λλ€λ μ¬μ€μ λ°νλμ΅λλ€. μ¬μ ν μ΄ λ¬Έμ μ μ λͺ©κ³Ό μΌμΉνμ§λ§ κ·Όλ³Έ μμΈμ΄ λ€λ¦ λλ€.
λλμ΅λλ€. 곡μ ν΄ μ£Όμ μ κ°μ¬ν©λλ€! :)
@Lukasa μ Hyperλ ν΄κ²°ν΄μΌ ν νλ₯ν λͺ©νμΈ κ² κ°μ΅λλ€.
@ μλ μ€ - λλ λΉμ μ΄ μΈκΈ ν λΉ μ²ν¬ μ±λ₯ λ¬Έμ μμ²μ λ urllib3μΌλ‘ μ‘°κΈ μ£Όμ λμλ€. λΉμ·ν μμ²μ΄ 20% κ°μν κ² κ°μ΅λλ€.
μμ²μμ λλ self.raw.streamμ λν νΈμΆμ (urllib3μμ) stream()μ μΈλΌμΈ ꡬνμΌλ‘ λ체νλ €κ³ μλνμ΅λλ€. μ μ΄λ λ΄ μ»΄ν¨ν°μμλ μμ²κ³Ό urllib3 μ¬μ΄μ μ²λ¦¬λμ ν¨μ¬ λ κ°κΉκ² λ§λλ κ² κ°μμ΅λλ€.
--- requests.repo/requests/models.py 2015-03-06 16:05:52.072509869 +0000
+++ requests/models.py 2015-03-07 20:49:25.618007438 +0000
@@ -19,6 +19,7 @@
from .packages.urllib3.fields import RequestField
from .packages.urllib3.filepost import encode_multipart_formdata
from .packages.urllib3.util import parse_url
+from .packages.urllib3.util.response import is_fp_closed
from .packages.urllib3.exceptions import (
DecodeError, ReadTimeoutError, ProtocolError, LocationParseError)
from .exceptions import (
@@ -652,8 +654,12 @@
try:
# Special case for urllib3.
try:
- for chunk in self.raw.stream(chunk_size, decode_content=True):
- yield chunk
+ while not is_fp_closed(self.raw._fp):
+ data = self.read(amt=chunk_size, decode_content=True)
+
+ if data:
+ yield data
+
except ProtocolError as e:
raise ChunkedEncodingError(e)
except DecodeError as e:
μ΄μ©λ©΄ λΉμ λ μ°¨μ΄κ° μλμ§ νμΈνκΈ° μν΄ λΉμ μ μ»΄ν¨ν°μμ κ°μ κ²μ μλν μ μμ΅λλ€.
(μ, is_fp_closedμ λν νΈμΆμ΄ μΊ‘μν νκ΄΄λΌλ κ²μ μκ³ μμ΅λλ€. μ¬κ°ν ν¨μΉκ° μλλΌ λ°μ΄ν° ν¬μΈνΈμΌ λΏμ λλ€)
@shazow νμ΄νΌκ° μ¬μ©νλ BufferedSocket
κ° λ³Έμ§μ μΌλ‘ μμ μ½κΈ°λ₯Ό λ°©μ§νμ¬ λ§μ λΉν¨μ¨μ±μ ν΄κ²°νκΈ°λ₯Ό λ°λλλ€. io.BufferedReader
κ΄λ²μνκ² μ¬μ©νκΈ° λλ¬Έμ Py3μ httplib
μ μ΄ λ¬Έμ κ° μλμ§ κΆκΈν©λλ€. μ΄λ BufferedSocket
μ κ±°μ λμΌν μ’
λ₯μ μ΄μ μ μ 곡ν΄μΌ νκΈ° λλ¬Έμ
λλ€.
κ·Έλ¬λ hyper
HTTP/1.1 κΈ°λ₯μ μ μ©νκ² μ¬μ©ν λ§νΌ μ±μ₯νλ©΄ μ΄λ¬ν λ€λ₯Έ ꡬνκ³Ό ν¨κ» λ²€μΉλ§νΉνκ³ hyper
μ΅λν 빨리 λ§λ€κΈ° μν΄ λ
Έλ ₯ν΄μΌ ν©λλ€.
κ±°μ 1λ λμ λΉνμ± μνμ λλ€. νμ.
λλ 10 λ°° λ μ¬μ©νμ¬ requests
μ λΉν΄ urllib3
.
λ¬Έμ κ° urllib3μ HTTPResponse
ν΄λμ€ λ΄μ μλ€κ³ μκ°ν©λλ€. iteratorλ‘ μ½μ λ μ²λ¦¬λμ μ λ§ λμ©λλ€. λ΄ μ½λκ° λ§€μ° μΆμ
ν ν΄νΉμΌλ‘ μλνκ³ μμ΅λλ€. urllib3μμ μ¬μ©νλ λ°μ€μ΄ κ·Έμ΄μ§ httplib.HTTPResponse
κ°μ²΄λ₯Ό λ°ννκ³ μ²λ¦¬λ λ¬Έμ λ₯Ό ν΄κ²°νλ κ² κ°μ΅λλ€.
ν₯λ―Έλ‘μ΄ μ¬μ€: urllib3μ HTTPResponse
μνΌν΄λμ€λ io.IOBase
μ
λλ€. Python3μ httplib.HTTPResponse
μνΌν΄λμ€λ io.BufferedIOBase
μ
λλ€. μ΄μ κ΄λ ¨μ΄ μλμ§ κΆκΈν©λλ€.