From 4339714ccccea691f449b6cde097c5a7e44d6a0b Mon Sep 17 00:00:00 2001 From: deftasparagusanaconda <101266955+deftasparagusanaconda@users.noreply.github.com> Date: Mon, 2 Nov 2026 10:57:44 +0530 Subject: [PATCH 1/4] perf: reduce arb pickle size by ~50% use python's native int pickling instead of hexadecimal --- src/flint/types/arb.pyx | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/flint/types/arb.pyx b/src/flint/types/arb.pyx index 44f7a48e..004dc4b3 100644 --- a/src/flint/types/arb.pyx +++ b/src/flint/types/arb.pyx @@ -35,14 +35,6 @@ cimport cython ctx = thectx -def _arb_from_pickle(mid, rad): - if isinstance(mid, tuple): - mid = tuple(int(x, 16) for x in mid) - if isinstance(rad, tuple): - rad = tuple(int(x, 16) for x in rad) - return arb(mid, rad) - - # cdef _str_trunc(s, trunc=0): # if trunc > 0 and len(s) > 3 * trunc: # left = right = trunc @@ -416,10 +408,9 @@ cdef class arb(flint_scalar): return (mid, rad) def __reduce__(self): - # Hex avoids the decimal digit limit in text pickle protocols. mid, rad = self._to_arfs() if mid.is_finite(): - mid = tuple(hex(x) for x in mid.man_exp()) + mid = tuple(map(int, mid.man_exp())) elif mid.is_nan(): mid = "nan" elif mid.is_pos_inf(): @@ -427,10 +418,10 @@ cdef class arb(flint_scalar): else: mid = "-inf" if rad.is_finite(): - rad = tuple(hex(x) for x in rad.man_exp()) + rad = tuple(map(int, rad.man_exp())) else: rad = "inf" - return (_arb_from_pickle, (mid, rad)) + return (arb, (mid, rad)) def repr(self): mid, rad = self._to_arfs() From 58f028f90523041c487772dcdb7b24edc6f991d1 Mon Sep 17 00:00:00 2001 From: deftasparagusanaconda <101266955+deftasparagusanaconda@users.noreply.github.com> Date: Tue, 3 Nov 2026 18:52:12 +0530 Subject: [PATCH 2/4] fix: arb supports pickling protocols 0 and 1 using int.to_bytes() and int.from_bytes() instead of native int pickling fmpz still does not support it. fix later. --- src/flint/types/arb.pyx | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/flint/types/arb.pyx b/src/flint/types/arb.pyx index 004dc4b3..e8aa7254 100644 --- a/src/flint/types/arb.pyx +++ b/src/flint/types/arb.pyx @@ -34,6 +34,12 @@ cimport cython ctx = thectx +def _arb_from_pickle(mid, rad): + if isinstance(mid, tuple): + mid = tuple(int.from_bytes(x, signed=True) for x in mid) + if isinstance(rad, tuple): + rad = tuple(int.from_bytes(x, signed=True) for x in rad) + return arb(mid, rad) # cdef _str_trunc(s, trunc=0): # if trunc > 0 and len(s) > 3 * trunc: @@ -410,7 +416,7 @@ cdef class arb(flint_scalar): def __reduce__(self): mid, rad = self._to_arfs() if mid.is_finite(): - mid = tuple(map(int, mid.man_exp())) + mid = tuple(int(x).to_bytes((x.bit_length()+8)//8, 'big', signed=True) for x in mid.man_exp()) elif mid.is_nan(): mid = "nan" elif mid.is_pos_inf(): @@ -418,10 +424,10 @@ cdef class arb(flint_scalar): else: mid = "-inf" if rad.is_finite(): - rad = tuple(map(int, rad.man_exp())) + rad = tuple(int(x).to_bytes((x.bit_length()+8)//8, 'big', signed=True) for x in rad.man_exp()) else: rad = "inf" - return (arb, (mid, rad)) + return (_arb_from_pickle, (mid, rad)) def repr(self): mid, rad = self._to_arfs() From fa18c77c4a17fa0e1c3f39f4d8ddbf9ebdf46d0b Mon Sep 17 00:00:00 2001 From: Lalremruata Chongmang <101266955+deftasparagusanaconda@users.noreply.github.com> Date: Tue, 3 Nov 2026 20:08:07 +0530 Subject: [PATCH 3/4] fix: explicit big-endian int unpacking since tests didnt pass for 3.10 --- src/flint/types/arb.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/flint/types/arb.pyx b/src/flint/types/arb.pyx index e8aa7254..21513c47 100644 --- a/src/flint/types/arb.pyx +++ b/src/flint/types/arb.pyx @@ -36,9 +36,9 @@ ctx = thectx def _arb_from_pickle(mid, rad): if isinstance(mid, tuple): - mid = tuple(int.from_bytes(x, signed=True) for x in mid) + mid = tuple(int.from_bytes(x, 'big', signed=True) for x in mid) if isinstance(rad, tuple): - rad = tuple(int.from_bytes(x, signed=True) for x in rad) + rad = tuple(int.from_bytes(x, 'big', signed=True) for x in rad) return arb(mid, rad) # cdef _str_trunc(s, trunc=0): From 337ffc01e20d1d61c6632e1f29a30aae188df5ff Mon Sep 17 00:00:00 2001 From: deftasparagusanaconda <101266955+deftasparagusanaconda@users.noreply.github.com> Date: Wed, 4 Nov 2026 09:37:29 +0530 Subject: [PATCH 4/4] =?UTF-8?q?perf(pickle):=20protocols=20=E2=89=A52=20pi?= =?UTF-8?q?ckle=20ints=20natively?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/flint/types/arb.pyx | 42 ++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/src/flint/types/arb.pyx b/src/flint/types/arb.pyx index 21513c47..6eb4b23b 100644 --- a/src/flint/types/arb.pyx +++ b/src/flint/types/arb.pyx @@ -413,21 +413,37 @@ cdef class arb(flint_scalar): arf_set_mag(rad.val, arb_radref(self.val)) return (mid, rad) - def __reduce__(self): + def __reduce_ex__(self, protocol: int): mid, rad = self._to_arfs() - if mid.is_finite(): - mid = tuple(int(x).to_bytes((x.bit_length()+8)//8, 'big', signed=True) for x in mid.man_exp()) - elif mid.is_nan(): - mid = "nan" - elif mid.is_pos_inf(): - mid = "inf" - else: - mid = "-inf" - if rad.is_finite(): - rad = tuple(int(x).to_bytes((x.bit_length()+8)//8, 'big', signed=True) for x in rad.man_exp()) + + if protocol < 2: # protocols 0 and 1 pickle ints inefficiently + if mid.is_finite(): + mid = tuple(int(x).to_bytes((x.bit_length()+8)//8, 'big', signed=True) for x in mid.man_exp()) + elif mid.is_nan(): + mid = "nan" + elif mid.is_pos_inf(): + mid = "inf" + else: + mid = "-inf" + if rad.is_finite(): + rad = tuple(int(x).to_bytes((x.bit_length()+8)//8, 'big', signed=True) for x in rad.man_exp()) + else: + rad = "inf" + return (_arb_from_pickle, (mid, rad)) else: - rad = "inf" - return (_arb_from_pickle, (mid, rad)) + if mid.is_finite(): + mid = tuple(map(int, mid.man_exp())) + elif mid.is_nan(): + mid = "nan" + elif mid.is_pos_inf(): + mid = "inf" + else: + mid = "-inf" + if rad.is_finite(): + rad = tuple(map(int, rad.man_exp())) + else: + rad = "inf" + return (arb, (mid, rad)) def repr(self): mid, rad = self._to_arfs()