Skip to content

Commit 2f44dba

Browse files
authored
BUG: Fix memory leak in to_json for time objects (#50794)
1 parent 7483414 commit 2f44dba

File tree

3 files changed

+12
-3
lines changed

3 files changed

+12
-3
lines changed

asv_bench/benchmarks/io/json.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,8 @@ def time_float_longint_str_lines(self):
294294
class ToJSONMem:
295295
def setup_cache(self):
296296
df = DataFrame([[1]])
297-
frames = {"int": df, "float": df.astype(float)}
297+
df2 = DataFrame(range(8), date_range("1/1/2000", periods=8, freq="T"))
298+
frames = {"int": df, "float": df.astype(float), "datetime": df2}
298299

299300
return frames
300301

@@ -308,5 +309,10 @@ def peakmem_float(self, frames):
308309
for _ in range(100_000):
309310
df.to_json()
310311

312+
def peakmem_time(self, frames):
313+
df = frames["datetime"]
314+
for _ in range(10_000):
315+
df.to_json(orient="table")
316+
311317

312318
from ..pandas_vb_common import setup # noqa: F401 isort:skip

doc/source/whatsnew/v2.0.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -874,6 +874,7 @@ Performance improvements
874874
- Performance improvement in :func:`read_csv` when passing :func:`to_datetime` lambda-function to ``date_parser`` and inputs have mixed timezone offsetes (:issue:`35296`)
875875
- Performance improvement in :meth:`.SeriesGroupBy.value_counts` with categorical dtype (:issue:`46202`)
876876
- Fixed a reference leak in :func:`read_hdf` (:issue:`37441`)
877+
- Fixed a memory leak in :meth:`DataFrame.to_json` and :meth:`Series.to_json` when serializing datetimes and timedeltas (:issue:`40443`)
877878

878879
.. ---------------------------------------------------------------------------
879880
.. _whatsnew_200.bug_fixes:

pandas/_libs/src/ujson/python/objToJSON.c

+4-2
Original file line numberDiff line numberDiff line change
@@ -350,13 +350,15 @@ static char *PyUnicodeToUTF8(JSOBJ _obj, JSONTypeContext *tc,
350350
static char *NpyDateTimeToIsoCallback(JSOBJ Py_UNUSED(unused),
351351
JSONTypeContext *tc, size_t *len) {
352352
NPY_DATETIMEUNIT base = ((PyObjectEncoder *)tc->encoder)->datetimeUnit;
353-
return int64ToIso(GET_TC(tc)->longValue, base, len);
353+
GET_TC(tc)->cStr = int64ToIso(GET_TC(tc)->longValue, base, len);
354+
return GET_TC(tc)->cStr;
354355
}
355356

356357
/* JSON callback. returns a char* and mutates the pointer to *len */
357358
static char *NpyTimeDeltaToIsoCallback(JSOBJ Py_UNUSED(unused),
358359
JSONTypeContext *tc, size_t *len) {
359-
return int64ToIsoDuration(GET_TC(tc)->longValue, len);
360+
GET_TC(tc)->cStr = int64ToIsoDuration(GET_TC(tc)->longValue, len);
361+
return GET_TC(tc)->cStr;
360362
}
361363

362364
/* JSON callback */

0 commit comments

Comments
 (0)