Python 애플리케이션 시작 시간을 단축하는 방법

6607 단어 python
pipenv 시작 시간이 크게 개선된 9.0.2가 릴리스되었다고 들었습니다.






케네스 레이츠 🐍










막대한 CLI 속도 향상이 포함된 Pipenv v9.0.2가 출시되었습니다! pipenv.org


오후 15:53 ​​- 2018년 1월 16일









금방 해봤는데 빠르다는 느낌은 못받았습니다. 그래서 파이썬 3.7의 새로운 기능으로 조사해 보았다.

이 기사에서는 기능과 사용 방법을 소개합니다.


시작 시간 ≒ 가져오기 시간



예를 들어 pipenv -h의 실행 시간은 도움말 메시지를 표시하는 시간보다 훨씬 깁니다.

일반적으로 응용 프로그램이 시작되면 환경 변수 또는 구성 파일 로드와 같은 일부 시작 프로세스가 있습니다.

Python 응용 프로그램의 경우 모듈 가져오기가 시작 시간의 대부분을 차지합니다. 예를 들어 pipenv --version는 약 800ms가 걸리고 import pipenv는 700ms가 걸립니다.

$ time local/py37/bin/python3 -c 'import pipenv'

real    0m0.696s
user    0m0.648s
sys     0m0.048s

$ time local/py37/bin/pipenv --version
pipenv, version 9.0.3

real    0m0.812s
user    0m0.761s
sys     0m0.052s


모듈 가져오기 시간 표시



Python 3.7에는 모듈 가져오기 시간을 표시하는 새로운 기능이 있습니다.

이 기능은 -X importtime 옵션 또는 PYTHONPROFILEIMPORTTIME 환경 변수로 활성화됩니다.

예를 들어 다음과 같이 pipenv의 가져오기 시간을 프로파일링할 수 있습니다.

python3.7 -X importtime -c 'import pipenv' 2> pipenv-imports


또는

PYTHONPROFILEIMPORTTIME=1 pipenv --version 2>pipenv-imports


Here is example output of pipenv --version

가져오기 시간 조사



마지막 출력에서 ​​다음 행을 볼 수 있습니다.

import time: self [us] | cumulative | imported package
...
import time:      3246 |     578972 |   pipenv.cli
import time:       507 |     579479 | pipenv


마지막 줄에서 579479는 import pipenv가 579 479us를 차지했음을 의미합니다.

pipenv를 가져오는 동안 다른 많은 모듈을 가져옵니다. 위의 예에서 pipenv imports pipenv.cli 를 볼 수 있습니다. 하위 가져오기는 2개의 공백으로 들여쓰기됩니다.

마지막 줄을 다시 참조하십시오. 507은 pipenv 모듈을 실행할 때 507us만 사용했음을 의미합니다. 579 479 - 507 = 578 972us는 하위 가져오기에 사용됩니다.

느린 부분 찾기



출력에서 느린 하위 트리를 찾아봅시다. 일부 라인을 선택했습니다.

import time: self [us] | cumulative | imported package
...
import time:     86500 |     179327 | pkg_resources
...
import time:       385 |     236655 |             IPython
import time:        22 |     236677 |           IPython.core
import time:        26 |     236703 |         IPython.core.magic
import time:       978 |     237680 |       dotenv.ipython
import time:       199 |     239032 |     dotenv
...
...
import time:      3246 |     578972 |   pipenv.cli
import time:       507 |     579479 | pipenv


pkg_resources



보시다시피 가져오기pkg_resources가 느립니다.
놀랍게도 pkg_resources는 들여쓰기가 되어 있지 않습니다. pipenv 의 하위 가져오기가 아닙니다.

모듈이 아닌 pkg_resources 스크립트에서 pipenv를 가져옴을 의미합니다.

$ cat local/py37/bin/pipenv
#!/home/inada-n/local/py37/bin/python3.7
# EASY-INSTALL-ENTRY-SCRIPT: 'pipenv==9.0.3','console_scripts','pipenv'
__requires__ = 'pipenv==9.0.3'
import re
import sys
from pkg_resources import load_entry_point

if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
    sys.exit(
        load_entry_point('pipenv==9.0.3', 'console_scripts', 'pipenv')()
    )


나쁜 소식: 가져오기pkg_resources가 느립니다. 이는 알려진 문제이며 이전 버전과의 호환성을 깨뜨리지 않고 수정하기 어렵습니다.

좋은 소식: pkg_resources 가져오기를 피할 수 있습니다!

$ local/py37/bin/pip install wheel
$ local/py37/bin/pip install -U --force-reinstall pipenv
$ time local/py37/bin/pipenv --version
pipenv, version 9.0.3

real    0m0.704s
user    0m0.653s
sys     0m0.052s


wheel이 설치되면 pip는 wheel을 빌드하고 설치합니다.

휠(.whl)에서 설치하는 것과 소스 패키지(.tar.gz)에서 설치하는 것은 다른 프로세스입니다.
휠에서 설치할 때 pkg_resources는 스크립트에서 사용되지 않습니다.

$ cat local/py37/bin/pipenv
#!/home/inada-n/local/py37/bin/python3.7

# -*- coding: utf-8 -*-
import re
import sys

from pipenv import cli

if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
    sys.exit(cli())


IPython



다음 부분을 참조하십시오.

import time:       385 |     236655 |             IPython
import time:        22 |     236677 |           IPython.core
import time:        26 |     236703 |         IPython.core.magic
import time:       978 |     237680 |       dotenv.ipython
import time:       199 |     239032 |     dotenv

pipenv 수입 dotenv , dotenv 수입 dotenv.ipython , 수입 IPython .

이것이 내 환경에서 pipenv가 느리게 시작되는 이유입니다. IPython이 설치되어 있습니다.

그런데 왜 IPython을 수입해야 할까요? 나는 dotenv 소스를 읽었고 그것이 IPython의 확장을 위한 것임을 알았습니다.

확실히 pipenv 및 많은 dotenv 사용자는 IPython 확장을 사용하지 않습니다.
요청에 따라 IPython을 가져오는 dotenv에 pull request을 만들었습니다.

그리고 pipenv에는 dotenv의 자체 사본이 있으므로 dotenv.ipython를 완전히 제거하는 pipenv에 pull request을 만들었습니다.

결론


pipenv --version의 시간을 800ms에서 500ms로 줄일 수 있습니다.

$ time local/py37/bin/pipenv --version
pipenv, version 9.0.3

real    0m0.503s
user    0m0.463s
sys     0m0.040s


가져오기 시간 프로파일링은 애플리케이션 시작 시간을 조사하고 최적화하는 매우 좋은 방법입니다.

좋은 웹페이지 즐겨찾기