Uploaded image for project: 'Python Driver'
  1. Python Driver
  2. PYTHON-4143

Optimize JSON encoding of int, float, str, and None

    • Type: Icon: Improvement Improvement
    • Resolution: Fixed
    • Priority: Icon: Unknown Unknown
    • 4.7
    • Affects Version/s: None
    • Component/s: JSON, Performance
    • None

      Context

      When encoding ints, floats, str, or None (depending on the JSONOptions set) our encoder will raise a TypeError and then catch the error and suppress it:

          elif json_options.json_mode == JSONMode.CANONICAL and isinstance(obj, int):
              if -(2**31) <= obj < 2**31:
                  return {"$numberInt": str(obj)}
              return {"$numberLong": str(obj)}
          elif json_options.json_mode != JSONMode.LEGACY and isinstance(obj, float):
              if math.isnan(obj):
                  return {"$numberDouble": "NaN"}
              elif math.isinf(obj):
                  representation = "Infinity" if obj > 0 else "-Infinity"
                  return {"$numberDouble": representation}
              elif json_options.json_mode == JSONMode.CANONICAL:
                  # repr() will return the shortest string guaranteed to produce the
                  # original value, when float() is called on it.
                  return {"$numberDouble": str(repr(obj))}
          raise TypeError("%r is not JSON serializable" % obj) # <---- Will be used for ints/floats
      

      This results in very poor performance. Instead we can skip the TypeError and directly return the int/float:

            Assignee:
            shane.harvey@mongodb.com Shane Harvey
            Reporter:
            shane.harvey@mongodb.com Shane Harvey
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: