[Python-checkins] r86169 - python/branches/py3k/Modules/_json.c

antoine.pitrou python-checkins at python.org
Thu Nov 4 17:51:32 CET 2010


Author: antoine.pitrou
Date: Thu Nov  4 17:51:32 2010
New Revision: 86169

Log:
Issue #10314: improve performance of JSON encoding with sort_keys=True



Modified:
   python/branches/py3k/Modules/_json.c

Modified: python/branches/py3k/Modules/_json.c
==============================================================================
--- python/branches/py3k/Modules/_json.c	(original)
+++ python/branches/py3k/Modules/_json.c	Thu Nov  4 17:51:32 2010
@@ -1387,8 +1387,6 @@
     PyObject *item = NULL;
     int skipkeys;
     Py_ssize_t idx;
-    PyObject *mapping;
-    static PyObject *code = NULL;
 
     if (open_dict == NULL || close_dict == NULL || empty_dict == NULL) {
         open_dict = PyUnicode_InternFromString("{");
@@ -1430,30 +1428,37 @@
     }
 
     if (PyObject_IsTrue(s->sort_keys)) {
-        if (code == NULL) {
-            code = Py_CompileString("sorted(d.items(), key=lambda kv: kv[0])",
-                                    "_json.c", Py_eval_input);
-            if (code == NULL)
-                goto bail;
-        }
-
-        mapping = PyDict_New();
-        if (mapping == NULL)
+        /* First sort the keys then replace them with (key, value) tuples. */
+        Py_ssize_t i, nitems;
+        items = PyMapping_Keys(dct);
+        if (items == NULL)
             goto bail;
-        if (PyDict_SetItemString(mapping, "d", dct) == -1) {
-            Py_DECREF(mapping);
+        if (!PyList_Check(items)) {
+            PyErr_SetString(PyExc_ValueError, "keys must return list");
             goto bail;
         }
-        items = PyEval_EvalCode((PyCodeObject *)code, PyEval_GetGlobals(), mapping);
-        Py_DECREF(mapping);
-        } else {
-        items = PyMapping_Items(dct);
+        if (PyList_Sort(items) < 0)
+            goto bail;
+        nitems = PyList_GET_SIZE(items);
+        for (i = 0; i < nitems; i++) {
+            PyObject *key, *value;
+            key = PyList_GET_ITEM(items, i);
+            value = PyDict_GetItem(dct, key);
+            item = PyTuple_Pack(2, key, value);
+            if (item == NULL)
+                goto bail;
+            PyList_SET_ITEM(items, i, item);
+            Py_DECREF(key);
         }
-        if (items == NULL)
+    }
+    else {
+        items = PyMapping_Items(dct);
+    }
+    if (items == NULL)
         goto bail;
     it = PyObject_GetIter(items);
-        Py_DECREF(items);
-        if (it == NULL)
+    Py_DECREF(items);
+    if (it == NULL)
         goto bail;
     skipkeys = PyObject_IsTrue(s->skipkeys);
     idx = 0;


More information about the Python-checkins mailing list