| commit ac4637fbc4e72bd59f221d9bba19127820d21023 |
| Author: Joakim Hamren <joakim.hamren@gmail.com> |
| Date: Sat Feb 4 16:36:14 2017 +0100 |
| |
| Following std json handling of None dict key |
| |
| Previously a None dict item key would be outputted in JSON as "None". |
| To better align with the standard json module this was changed to output |
| "null". There's no proper representation of null object keys in JSON so |
| this is implementation specific but it seems more natural to follow |
| suit when it can be done without a significant performance hit. |
| |
| Added and used branch prediction macros (LIKELY/UNLIKELY) as well. |
| |
| diff --git a/lib/ultrajson.h b/lib/ultrajson.h |
| index 6c1dbc1..ca82a29 100644 |
| --- a/lib/ultrajson.h |
| +++ b/lib/ultrajson.h |
| @@ -117,6 +117,14 @@ typedef uint32_t JSUINT32; |
| |
| #define INLINE_PREFIX inline |
| |
| +#ifdef __GNUC__ |
| +#define LIKELY(x) __builtin_expect(!!(x), 1) |
| +#define UNLIKELY(x) __builtin_expect(!!(x), 0) |
| +#else |
| +#define LIKELY(x) (x) |
| +#define UNLIKELY(x) (x) |
| +#endif |
| + |
| typedef uint8_t JSUINT8; |
| typedef uint16_t JSUTF16; |
| typedef uint32_t JSUTF32; |
| diff --git a/python/objToJSON.c b/python/objToJSON.c |
| index adea2f6..41d4289 100644 |
| --- a/python/objToJSON.c |
| +++ b/python/objToJSON.c |
| @@ -488,6 +488,12 @@ static int Dict_iterNext(JSOBJ obj, JSONTypeContext *tc) |
| else |
| if (!PyString_Check(GET_TC(tc)->itemName)) |
| { |
| + if (UNLIKELY(GET_TC(tc)->itemName == Py_None)) |
| + { |
| + GET_TC(tc)->itemName = PyString_FromString("null"); |
| + return 1; |
| + } |
| + |
| GET_TC(tc)->itemName = PyObject_Str(GET_TC(tc)->itemName); |
| #if PY_MAJOR_VERSION >= 3 |
| itemNameTmp = GET_TC(tc)->itemName; |
| @@ -743,7 +749,7 @@ static void Object_beginTypeContext (JSOBJ _obj, JSONTypeContext *tc, JSONObject |
| return; |
| } |
| else |
| - if (PyString_Check(obj) && !PyHasAttrStringPreserveErr(obj, "__json__")) |
| + if (PyString_Check(obj) && LIKELY(!PyHasAttrStringPreserveErr(obj, "__json__"))) |
| { |
| PRINTMARK(); |
| pc->PyTypeToJSON = PyStringToUTF8; tc->type = JT_UTF8; |
| @@ -837,7 +843,7 @@ ISITERABLE: |
| } |
| */ |
| |
| - if (PyObject_HasAttrString(obj, "toDict")) |
| + if (UNLIKELY(PyObject_HasAttrString(obj, "toDict"))) |
| { |
| PyObject* toDictFunc = PyObject_GetAttrString(obj, "toDict"); |
| PyObject* tuple = PyTuple_New(0); |
| @@ -863,7 +869,7 @@ ISITERABLE: |
| return; |
| } |
| else |
| - if (PyObject_HasAttrString(obj, "__json__")) |
| + if (UNLIKELY(PyObject_HasAttrString(obj, "__json__"))) |
| { |
| PyObject* toJSONFunc = PyObject_GetAttrString(obj, "__json__"); |
| PyObject* tuple = PyTuple_New(0); |