[diffoscope] 01/01: WIP on C-based speedups

Chris Lamb chris at chris-lamb.co.uk
Mon Jan 9 17:31:24 CET 2017


This is an automated email from the git hooks/post-receive script.

lamby pushed a commit to branch lamby/wip/cython
in repository diffoscope.

commit 2768c7bbd1c6450ba6525c634eb2f5be6ec400a4
Author: Chris Lamb <lamby at debian.org>
Date:   Sun Jan 1 11:43:19 2017 +0000

    WIP on C-based speedups
---
 .gitignore                                         |  1 +
 debian/control                                     |  5 ++--
 diffoscope/main.py                                 |  8 +++++-
 diffoscope/presenters/html/html.py                 |  2 +-
 .../{presenters/html/linediff.py => speedups.py}   |  0
 .../{presenters/html/linediff.py => speedups.pyx}  | 32 ++++++++++++++--------
 setup.py                                           | 12 +++++++-
 7 files changed, 44 insertions(+), 16 deletions(-)

diff --git a/.gitignore b/.gitignore
index eb4cf19..4bcc6b6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,4 @@
 /htmlcov/
 favicon.png
 /debian/*.1
+/diffoscope/speedups.c
diff --git a/debian/control b/debian/control
index 0d1a7a3..d8af567 100644
--- a/debian/control
+++ b/debian/control
@@ -14,6 +14,7 @@ Build-Depends:
  binutils-multiarch <!nocheck>,
  caca-utils <!nocheck>,
  colord <!nocheck>,
+ cython3,
  debhelper (>= 10),
  default-jdk-headless <!nocheck> | default-jdk <!nocheck>,
  dh-python (>= 2.20160818~),
@@ -35,7 +36,7 @@ Build-Depends:
  poppler-utils <!nocheck>,
  python-argcomplete,
  jsbeautifier <!nocheck>,
- python3-all,
+ python3-all-dev,
  python3-debian <!nocheck>,
  python3-docutils,
  python3-guestfs <!nocheck>,
@@ -58,7 +59,7 @@ Vcs-Git: https://anonscm.debian.org/git/reproducible/diffoscope.git
 Vcs-Browser: https://anonscm.debian.org/git/reproducible/diffoscope.git
 
 Package: diffoscope
-Architecture: all
+Architecture: any
 Suggests:
  libjs-jquery,
 Breaks:
diff --git a/diffoscope/main.py b/diffoscope/main.py
index 97369fe..5bf956b 100644
--- a/diffoscope/main.py
+++ b/diffoscope/main.py
@@ -28,7 +28,9 @@ import argparse
 import traceback
 import contextlib
 
-from . import VERSION
+from importlib.machinery import ExtensionFileLoader
+
+from . import VERSION, speedups
 from .exc import RequiredToolNotFound
 from .tools import tool_required, OS_NAMES, get_current_os
 from .config import Config
@@ -245,6 +247,10 @@ def run_diffoscope(parsed_args):
     # no output desired? print text to stdout
     if not any((parsed_args.text_output, parsed_args.html_output, parsed_args.html_output_directory)):
         parsed_args.text_output = "-"
+    logger.debug(
+        "Using compiled diffoscope.speedups: %s",
+        isinstance(speedups.__loader__, ExtensionFileLoader),
+    )
     logger.debug('Starting comparison')
     ProgressManager().setup(parsed_args)
     with Progress(1, parsed_args.path1) as p:
diff --git a/diffoscope/presenters/html/html.py b/diffoscope/presenters/html/html.py
index 9b9f897..567bfd1 100644
--- a/diffoscope/presenters/html/html.py
+++ b/diffoscope/presenters/html/html.py
@@ -43,11 +43,11 @@ import contextlib
 from diffoscope import VERSION
 from diffoscope.config import Config
 from diffoscope.logging import logger
+from diffoscope.speedups import linediff
 
 from ..icon import FAVICON_BASE64
 
 from . import templates
-from .linediff import linediff
 
 # minimum line size, we add a zero-sized breakable space every
 # LINESIZE characters
diff --git a/diffoscope/presenters/html/linediff.py b/diffoscope/speedups.py
similarity index 100%
copy from diffoscope/presenters/html/linediff.py
copy to diffoscope/speedups.py
diff --git a/diffoscope/presenters/html/linediff.py b/diffoscope/speedups.pyx
similarity index 82%
rename from diffoscope/presenters/html/linediff.py
rename to diffoscope/speedups.pyx
index 710ce36..6a5e5d9 100644
--- a/diffoscope/presenters/html/linediff.py
+++ b/diffoscope/speedups.pyx
@@ -18,7 +18,7 @@
 # along with diffoscope.  If not, see <https://www.gnu.org/licenses/>.
 
 
-def sane(x):
+cdef str sane(x):
     r = ""
     for i in x:
         j = ord(i)
@@ -29,7 +29,7 @@ def sane(x):
     return r
 
 
-def linediff(s, t, diffon, diffoff):
+cpdef str inediff(s, t, diffon, diffoff):
     '''
     Original line diff algorithm of diff2html. It's character based.
     '''
@@ -38,7 +38,8 @@ def linediff(s, t, diffon, diffoff):
     if len(t):
         t = ''.join([ sane(c) for c in t ])
 
-    m, n = len(s), len(t)
+    cdef m = len(s)
+    cdef n = len(t)
     d = [[(0, 0) for i in range(n+1)] for i in range(m+1)]
 
 
@@ -65,26 +66,35 @@ def linediff(s, t, diffon, diffoff):
         x, y = coord
         coord = d[x][y][1]
 
-    l1 = []
-    l2 = []
+    cdef list l1 = []
+    cdef list l2 = []
+
+    cdef int fx
+    cdef int fy
+    cdef int child_val
+    cdef int father_val
+
+    cdef int diff_0
+    cdef int diff_1
 
     for coord in l:
         cx, cy = coord
         child_val = d[cx][cy][0]
 
-        father_coord = d[cx][cy][1]
-        fx, fy = father_coord
+        fx = d[cx][cy][1][0]
+        fy = d[cx][cy][1][1]
         father_val = d[fx][fy][0]
 
-        diff = (cx-fx, cy-fy)
+        diff_0 = cx - fx
+        diff_1 = cy - fy
 
-        if diff == (0, 1):
+        if diff_0 == 0 and diff_1 == 0:
             l1.append("")
             l2.append(diffon + t[fy] + diffoff)
-        elif diff == (1, 0):
+        elif diff_0 == 1 and diff_1 == 0:
             l1.append(diffon + s[fx] + diffoff)
             l2.append("")
-        elif child_val-father_val == 1:
+        elif child_val - father_val == 1:
             l1.append(diffon + s[fx] + diffoff)
             l2.append(diffon + t[fy] + diffoff)
         else:
diff --git a/setup.py b/setup.py
index 10b8d04..4fb71cd 100644
--- a/setup.py
+++ b/setup.py
@@ -3,9 +3,18 @@
 import sys
 import diffoscope
 
-from setuptools import setup, find_packages
+from setuptools import setup, find_packages, Extension
 from setuptools.command.test import test as TestCommand
 
+from Cython.Build import cythonize
+
+extensions = [
+    Extension('diffoscope.speedups', [
+        'diffoscope/speedups.pyx',
+    ]),
+]
+
+extensions = cythonize(extensions)
 
 class PyTest(TestCommand):
     user_options = [('pytest-args=', 'a', "Arguments to pass to py.test")]
@@ -33,6 +42,7 @@ setup(
     license='GPL-3+',
     url='https://diffoscope.org/',
     packages=find_packages(),
+    ext_modules=extensions,
     tests_require=['pytest'],
     cmdclass = {'test': PyTest},
     entry_points={

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/diffoscope.git


More information about the diffoscope mailing list