Skip to content

Commit

Permalink
dual python2/3 packaging
Browse files Browse the repository at this point in the history
  • Loading branch information
shoyer committed Nov 12, 2014
1 parent e7cad29 commit 99a21e4
Show file tree
Hide file tree
Showing 18 changed files with 153 additions and 7 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Expand Up @@ -4,4 +4,5 @@ MANIFEST
*.egg-info
*.c
*.pyc
*.so
*.so
_version.py
1 change: 0 additions & 1 deletion cyordereddict/_version.py

This file was deleted.

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
5 changes: 5 additions & 0 deletions python3/cyordereddict/__init__.py
@@ -0,0 +1,5 @@
from ._cyordereddict import OrderedDict

from .benchmark.benchmark import benchmark

from ._version import __version__
File renamed without changes.
Empty file.
57 changes: 57 additions & 0 deletions python3/cyordereddict/benchmark/benchmark.py
@@ -0,0 +1,57 @@
import sys

import cyordereddict

from .magic_timeit import magic_timeit


SETUP_TEMPLATE = """
from {module} import OrderedDict
list_data = list(enumerate(range(1000)))
dict_data = dict(list_data)
ordereddict = OrderedDict(dict_data)
"""

BENCHMARKS = cyordereddict.OrderedDict([
('``__init__`` empty', 'OrderedDict()'),
('``__init__`` list', 'OrderedDict(list_data)'),
('``__init__`` dict', 'OrderedDict(dict_data)'),
('``__setitem__``', "ordereddict[-1] = False"),
('``__getitem__``', "ordereddict[100]"),
('``update``', "ordereddict.update(dict_data)"),
('``__iter__``', "list(ordereddict)"),
('``items``', "ordereddict.items()"),
('``__contains__``', "100 in ordereddict"),
])

if sys.version_info[0] >= 3:
BENCHMARKS['``items``'] = 'list(%s)' % BENCHMARKS['``items``']


def _time_execution(module, code, repeat):
setup = SETUP_TEMPLATE.format(module=module)
result = magic_timeit(setup, code, repeat=repeat, force_ms=True)
return result['timing']


def _calculate_benchmarks(repeat):
all_results = []
for bench_name, code in BENCHMARKS.items():
stdlib_speed = _time_execution('collections', code, repeat)
cy_speed = _time_execution('cyordereddict', code, repeat)
ratio_str = '%.1f' % (stdlib_speed / cy_speed)
all_results.append((bench_name, '``%s``' % code, ratio_str))
return all_results


def benchmark(repeat=10):
"""Benchmark cyordereddict.OrderedDict against collections.OrderedDict
"""
columns = ['Test', 'Code', 'Ratio (stdlib / cython)']
res = _calculate_benchmarks(repeat)
try:
from tabulate import tabulate
print(tabulate(res, columns, 'rst'))
except ImportError:
print(columns)
print(res)
77 changes: 77 additions & 0 deletions python3/cyordereddict/benchmark/magic_timeit.py
@@ -0,0 +1,77 @@
# Modified from Wes McKinley's vbench:
# https://github.com/pydata/vbench/blob/master/vbench/benchmark.py

# Modified from IPython project, http://ipython.org


def magic_timeit(setup, stmt, ncalls=None, repeat=3, force_ms=False):
"""Time execution of a Python statement or expression
Usage:\\
%timeit [-n<N> -r<R> [-t|-c]] statement
Time execution of a Python statement or expression using the timeit
module.
Options:
-n<N>: execute the given statement <N> times in a loop. If this value
is not given, a fitting value is chosen.
-r<R>: repeat the loop iteration <R> times and take the best result.
Default: 3
-t: use time.time to measure the time, which is the default on Unix.
This function measures wall time.
-c: use time.clock to measure the time, which is the default on
Windows and measures wall time. On Unix, resource.getrusage is used
instead and returns the CPU user time.
-p<P>: use a precision of <P> digits to display the timing result.
Default: 3
Examples:
In [1]: %timeit pass
10000000 loops, best of 3: 53.3 ns per loop
In [2]: u = None
In [3]: %timeit u is None
10000000 loops, best of 3: 184 ns per loop
In [4]: %timeit -r 4 u == None
1000000 loops, best of 4: 242 ns per loop
In [5]: import time
In [6]: %timeit -n1 time.sleep(2)
1 loops, best of 3: 2 s per loop
The times reported by %timeit will be slightly higher than those
reported by the timeit.py script when variables are accessed. This is
due to the fact that %timeit executes the statement in the namespace
of the shell, compared with timeit.py, which uses a single setup
statement to import function or create variables. Generally, the bias
does not matter as long as results from timeit.py are not mixed with
those from %timeit."""

import timeit
import math

units = ["s", "ms", 'us', "ns"]
scaling = [1, 1e3, 1e6, 1e9]

timer = timeit.Timer(stmt, setup)

if ncalls is None:
# determine number so that 0.2 <= total time < 2.0
number = 1
for _ in range(1, 10):
if timer.timeit(number) >= 0.1:
break
number *= 10
else:
number = ncalls

best = min(timer.repeat(repeat, number)) / number

if force_ms:
order = 1
else:
if best > 0.0 and best < 1000.0:
order = min(-int(math.floor(math.log10(best)) // 3), 3)
elif best >= 1000.0:
order = 0
else:
order = 3

return {'loops': number,
'repeat': repeat,
'timing': best * scaling[order],
'units': units[order]}
File renamed without changes.
17 changes: 12 additions & 5 deletions setup.py
Expand Up @@ -5,10 +5,16 @@

# adapted from cytoolz: https://github.com/pytoolz/cytoolz/blob/master/setup.py

info = {}
filename = os.path.join('cyordereddict', '_version.py')
exec(compile(open(filename, "rb").read(), filename, 'exec'), info)
VERSION = info['__version__']
VERSION = '0.1.1-dev'

if sys.version_info[0] == 2:
base_dir = 'python2'
elif sys.version_info[0] == 3:
base_dir = 'python3'

filename = os.path.join(base_dir, 'cyordereddict', '_version.py')
with open(filename, 'w') as f:
f.write('__version__ = %r' % VERSION)

try:
from Cython.Build import cythonize
Expand Down Expand Up @@ -36,7 +42,7 @@
use_cython = False

ext = '.pyx' if use_cython else '.c'
source = os.path.join("cyordereddict", "_cyordereddict")
source = os.path.join(base_dir, "cyordereddict", "_cyordereddict")
ext_modules = [Extension("cyordereddict._cyordereddict", [source + ext])]
if use_cython:
ext_modules = cythonize(ext_modules)
Expand All @@ -54,6 +60,7 @@
author='Stephan Hoyer',
author_email='shoyer@gmail.com',
packages=['cyordereddict', 'cyordereddict.benchmark'],
package_dir={'': base_dir},
ext_modules=ext_modules,
classifiers = [
'Development Status :: 3 - Alpha',
Expand Down

0 comments on commit 99a21e4

Please sign in to comment.