diff --git a/.gitignore b/.gitignore index 2a62691..0e1b4a7 100644 --- a/.gitignore +++ b/.gitignore @@ -5,8 +5,12 @@ /pyext-myclib/myclib.py /pyext-myclib/myclib_wrap.c /pyext-myclib/_myclib.cpython* +/pyext-mycythonlib/*.so +/pyext-mycythonlib/*.c +/pyext-mycythonlib/*.html .cache .benchmarks __pycache__ myrustlib.so +mycythonlib*.so /pyext-myrustlib/.gitignore diff --git a/Makefile b/Makefile index 847f8ec..53b0204 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: clean clean-test clean-pyc clean-build docs help +.PHONY: clean clean-test clean-pyc clean-build docs help test-python test-rust test-c test-cython compile-cython compile-rust compile-c clean: clean-build clean-pyc clean-test ## remove all build, test, coverage and Python artifacts @@ -6,6 +6,7 @@ clean-build: ## remove build artifacts rm -fr build/ rm -fr dist/ rm -fr .eggs/ + rm -fr .compiled find . -name '*.egg-info' -exec rm -fr {} + find . -name '*.egg' -exec rm -f {} + @@ -32,6 +33,9 @@ test-rust: ## run tests quickly with the default Python test-c: ## run tests quickly with the default Python py.test -v -s doubles_with_c_swig.py +test-cython: # run tests quickly with the default Python + py.test -v -s doubles_with_cython.py + test-all: ## run tests quickly with the default Python py.test -v -s doubles_all.py @@ -41,3 +45,14 @@ compile-rust: ## compile new rust lib compile-c: ## compile new c lib @cd pyext-myclib;python3 setup.py build_ext -i + +compile-cython: ## compile new cython lib + @cd pyext-mycythonlib;cythonize -a -i mycythonlib.pyx + @cp pyext-mycythonlib/mycythonlib*.so ./ + +compile-all: compile-rust compile-c compile-cython + +.compiled: compile-all + touch .compiled + +test: compile-all test-all diff --git a/doubles_all.py b/doubles_all.py index 742fd4c..0e46e4e 100644 --- a/doubles_all.py +++ b/doubles_all.py @@ -4,6 +4,7 @@ import itertools import numpy as np import myrustlib # <-- Importing Rust Implemented Library +import mycythonlib # <-- Importing Cython Implemented Library import sys sys.path.append('./pyext-myclib') @@ -101,3 +102,6 @@ def test_c_swig_bytes_once(benchmark): # def test_rust_regex(benchmark): # print(benchmark(myrustlib.count_doubles_regex, val)) + +def test_cython(benchmark): + print(benchmark(mycythonlib.count_doubles, val)) diff --git a/pyext-mycythonlib/mycythonlib.pyx b/pyext-mycythonlib/mycythonlib.pyx new file mode 100644 index 0000000..ebf8baf --- /dev/null +++ b/pyext-mycythonlib/mycythonlib.pyx @@ -0,0 +1,18 @@ +def count_doubles( unicode source ): + """Count number of doubles in a (unicode) string + + A double is counted for every character where the + character at the previous index in the string is + the same character as the current character. Thus + the string 'aaa' has two doubles. + """ + cdef Py_ssize_t count + count = 0 + if not source: + return count + char = source[0] + for next_char in source[1:]: + if next_char == char: + count += 1 + char = next_char + return count diff --git a/requirements.txt b/requirements.txt index 86c9ef6..37738dd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ pytest pytest-benchmark numpy +cython \ No newline at end of file