diff --git a/.travis.yml b/.travis.yml
index cc887390c712b58f1a07aac0b02e1228540d44ec..64391e8803d2cad88ae4587980ca5d4695da4b1a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -131,7 +131,7 @@ jobs:
       before_script:
         - sudo apt-get update
         - sudo apt-get install -y patchelf
-        - pypy3 -m pip install wheel auditwheel twine doctor-wheel cython
+        - pypy3 -m pip install -U wheel auditwheel twine doctor-wheel cython
       script:
         - pypy3 setup.py bdist_wheel
         - cd dist
diff --git a/Dockerfile b/Dockerfile
index b455368bdbd078adb682784977a3d023f74d2c22..537ccfc70d57156914f153b0e29d2d5cd5555a6f 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,7 +1,7 @@
 FROM python:3.8
 RUN apt-get update && \
     apt-get install -y patchelf
-RUN python -m pip install Cython pytest coverage pytest-cov auditwheel doctor-wheel twine
+RUN python -m pip install Cython pytest coverage pytest-cov
 
 WORKDIR /tmp/compile
 ADD . /tmp/compile/
diff --git a/README.md b/README.md
index 7e68f005c9305540af63775f114c441645f97ee2..48a11f089b113a4a20199a2b6a6772f37260d6f0 100644
--- a/README.md
+++ b/README.md
@@ -28,3 +28,5 @@ Alternatively, you can
 and I'll do my best to compile a wheel for you.
 
 In order to do that you must have `Cython` installed.
+
+Run the Dockerfile to launch unit tests locally.
diff --git a/docs/changelog.md b/docs/changelog.md
index 05cc96748e5c4e050e6ad2063144074295cedb6b..0abd45e13c494fe64283a73c7d82279bde6e38bf 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -1,6 +1,11 @@
 Changelog
 =========
 
+v2.9
+----
+
+* minor refactor: code deduplication
+
 v2.8
 ----
 
diff --git a/minijson.pyx b/minijson.pyx
index 6bd155b02e640a701249a6cfdbfae098d74c6b4f..05bcd2746632667078f4c05ab426015d25d67bca 100644
--- a/minijson.pyx
+++ b/minijson.pyx
@@ -341,7 +341,7 @@ cdef class MiniJSONEncoder:
         self.use_double = use_double
         self.use_strict_order = use_strict_order
 
-    def should_double_be_used(self, y) -> bool:
+    def should_double_be_used(self, y: float) -> bool:
         """
         A function that you are meant to overload that will decide on a per-case basis
         which representation should be used for given number.
@@ -514,18 +514,17 @@ cdef class MiniJSONEncoder:
                     cio.write(b'\x12')
                     cio.write(STRUCT_L.pack(length))
                     length = 5
+
+                data = data.items()
+
                 if self.use_strict_order:
-                    items = list(data.items())
-                    items.sort()
-                    for field_name, elem in items:
-                        cio.write(bytearray([len(field_name)]))
-                        cio.write(field_name.encode('utf-8'))
-                        length += self.dump(elem, cio)
-                else:
-                    for field_name, elem in data.items():
-                        cio.write(bytearray([len(field_name)]))
-                        cio.write(field_name.encode('utf-8'))
-                        length += self.dump(elem, cio)
+                    data = list(data)
+                    data.sort()  # sort implicitly will sort it by first value, which is the key
+
+                for field_name, elem in data:
+                    cio.write(bytearray([len(field_name)]))
+                    cio.write(field_name.encode('utf-8'))
+                    length += self.dump(elem, cio)
                 return length
             else:
                 if length <= 0xF:
@@ -542,16 +541,13 @@ cdef class MiniJSONEncoder:
                     cio.write(b'\x13')
                     cio.write(STRUCT_L.pack(length))
                     offset = 5
+                data = data.items()
                 if self.use_strict_order:
-                    items = list(data.items())
-                    items.sort()
-                    for key, value in items:
-                        offset += self.dump(key, cio)
-                        offset += self.dump(value, cio)
-                else:
-                    for key, value in data.items():
-                        offset += self.dump(key, cio)
-                        offset += self.dump(value, cio)
+                    data = list(data)
+                    data.sort()  # sort implicitly will sort it by first value, which is the key
+                for key, value in data:
+                    offset += self.dump(key, cio)
+                    offset += self.dump(value, cio)
                 return offset
         else:
             v = self.default(data)
diff --git a/setup.cfg b/setup.cfg
index 8a68a91442f4dcfa47fc75449b016eb792878128..a33a1d4363f0857101528da2834aac37858a7791 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,6 +1,6 @@
 # coding: utf-8
 [metadata]
-version = 2.8
+version = 2.9a1
 name = minijson
 long_description = file: README.md
 long_description_content_type = text/markdown; charset=UTF-8