diff --git a/.travis.yml b/.travis.yml index 584ddd24..41ee4f1f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,6 +14,7 @@ env: - TOXENV=pypy - TOXENV=pypy3 - TOXENV=flake8 + - TOXENV=perf before_install: - pip install codecov install: diff --git a/Makefile b/Makefile index a383d3c5..491131f9 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ # IMPORTANT: for compatibility with `python setup.py make [alias]`, ensure: -# 1. Every alias is preceded by @make (eg: @make alias) +# 1. Every alias is preceded by @[+]make (eg: @make alias) # 2. A maximum of one @make alias or command per line # # Sample makefile compatible with `python setup.py make`: @@ -21,6 +21,7 @@ testnose testsetup testcoverage + testperf installdev install build @@ -29,24 +30,26 @@ none alltests: - @make testcoverage - @make flake8 - @make testsetup + @+make testcoverage + @+make testperf + @+make flake8 + @+make testsetup all: - @make alltests - @make build + @+make alltests + @+make build flake8: - flake8 --max-line-length=80 --count --statistics --exit-zero tqdm/ - flake8 --max-line-length=80 --count --statistics --exit-zero examples/ - flake8 --max-line-length=80 --count --statistics --exit-zero . + @+flake8 --max-line-length=80 --count --statistics --exit-zero tqdm/ + @+flake8 --max-line-length=80 --count --statistics --exit-zero examples/ + @+flake8 --max-line-length=80 --count --statistics --exit-zero . + @+flake8 --max-line-length=80 --count --statistics --exit-zero tqdm/tests/ test: tox --skip-missing-interpreters testnose: - nosetests tqdm -d -v + nosetests tqdm --ignore-files="tests_perf\.py" -d -v testsetup: python setup.py check --restructuredtext --strict @@ -54,7 +57,10 @@ testsetup: testcoverage: rm -f .coverage # coverage erase - nosetests tqdm --with-coverage --cover-package=tqdm -d -v + nosetests tqdm --with-coverage --cover-package=tqdm --cover-erase --cover-min-percentage=80 --ignore-files="tests_perf\.py" -d -v + +testperf: # do not use coverage, slows down the perf test and fail + nosetests tqdm/tests/tests_perf.py -d -v installdev: python setup.py develop --uninstall diff --git a/setup.py b/setup.py index 32a655b5..4bd14aa1 100755 --- a/setup.py +++ b/setup.py @@ -7,10 +7,10 @@ import sys import subprocess # For Makefile parsing import shlex -try: # pragma: no cover +try: # pragma: no cover import ConfigParser import StringIO -except ImportError: # pragma: no cover +except ImportError: # pragma: no cover # Python 3 compatibility import configparser as ConfigParser import io as StringIO @@ -31,7 +31,8 @@ def parse_makefile_aliases(filepath): # Adding a fake section to make the Makefile a valid Ini file ini_str = '[root]\n' with open(filepath, 'r') as fd: - ini_str = ini_str + fd.read().replace('@make ', '') + ini_str = ini_str + fd.read().replace('\t@', '\t').\ + replace('\t+', '\t').replace('\tmake ', '\t') ini_fp = StringIO.StringIO(ini_str) # Parse using ConfigParser config = ConfigParser.RawConfigParser() diff --git a/tox.ini b/tox.ini index b5e52c06..524e873a 100644 --- a/tox.ini +++ b/tox.ini @@ -4,7 +4,7 @@ # and then run "tox" from this directory. [tox] -envlist = py26, py27, py32, py33, py34, pypy, pypy3, flake8, setup.py +envlist = py26, py27, py32, py33, py34, pypy, pypy3, flake8, setup.py, perf [testenv] passenv = TRAVIS TRAVIS_JOB_ID TRAVIS_BRANCH @@ -13,7 +13,7 @@ deps = coverage<4 coveralls commands = - nosetests --with-coverage --cover-package=tqdm -d -v tqdm/ + nosetests --with-coverage --cover-package=tqdm --ignore-files="tests_perf\.py" -d -v tqdm/ coveralls [testenv:flake8] @@ -22,6 +22,7 @@ commands = flake8 --max-line-length=80 --count --statistics --exit-zero tqdm/ flake8 --max-line-length=80 --count --statistics --exit-zero examples/ flake8 --max-line-length=80 --count --statistics --exit-zero . + flake8 --max-line-length=80 --count --statistics --exit-zero tqdm/tests/ [testenv:setup.py] deps = @@ -30,3 +31,9 @@ deps = commands = python setup.py check --restructuredtext --metadata --strict python setup.py make none + +[testenv:perf] +deps = + nose +commands = + nosetests tqdm/tests/tests_perf.py -d -v diff --git a/tqdm/_version.py b/tqdm/_version.py index a464a697..22716001 100644 --- a/tqdm/_version.py +++ b/tqdm/_version.py @@ -1,5 +1,5 @@ # Definition of the version number -version_info = 3, 1, 0 # major, minor, patch, -extra +version_info = 3, 1, 1 # major, minor, patch, -extra # Nice string for the version __version__ = '.'.join(map(str, version_info)).replace('.-', '-').strip('.-') diff --git a/tqdm/tests/tests_perf.py b/tqdm/tests/tests_perf.py new file mode 100644 index 00000000..831272fb --- /dev/null +++ b/tqdm/tests/tests_perf.py @@ -0,0 +1,76 @@ +from time import time + +try: + from StringIO import StringIO + _range = xrange +except: + from io import StringIO + _range = range + +from tqdm import trange +from tqdm import tqdm + + +_tic_toc = [None] + + +def tic(): + _tic_toc[0] = time() + + +def toc(): + return time() - _tic_toc[0] + + +def test_iter_overhead(): + """ Test overhead of iteration based tqdm """ + total = int(1e6) + + our_file = StringIO() + a = 0 + tic() + for i in trange(total, file=our_file): + a = a + i + time_tqdm = toc() + our_file.close() + + a = 0 + tic() + for i in _range(total): + a = a + i + time_bench = toc() + + # Compute relative overhead of tqdm against native range() + try: + assert(time_tqdm < 6 * time_bench) + except AssertionError: + raise AssertionError('trange(%g): %f, range(%g): %f' % + (total, time_tqdm, total, time_bench)) + + +def test_manual_overhead(): + """ Test overhead of manual tqdm """ + total = int(1e6) + + our_file = StringIO() + t = tqdm(total=total*10, file=our_file, leave=True) + a = 0 + tic() + for i in _range(total): + a = a + i + t.update(10) + time_tqdm = toc() + our_file.close() + + a = 0 + tic() + for i in _range(total): + a = a + i + time_bench = toc() + + # Compute relative overhead of tqdm against native range() + try: + assert(time_tqdm < 17 * time_bench) + except AssertionError: + raise AssertionError('tqdm(%g): %f, range(%g): %f' % + (total, time_tqdm, total, time_bench)) diff --git a/tqdm/tests/tests_tqdm.py b/tqdm/tests/tests_tqdm.py index 8b4119ae..780b1f0a 100644 --- a/tqdm/tests/tests_tqdm.py +++ b/tqdm/tests/tests_tqdm.py @@ -383,6 +383,7 @@ def test_close(): def test_smoothing(): """ Test exponential weighted average smoothing """ + # -- Test disabling smoothing our_file = StringIO() for i in tqdm(_range(3), file=our_file, smoothing=None, leave=True):