From 63c3ab6b736535cb9b7f633cd6c5a09db52fd9f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Oudompheng?= Date: Sun, 19 Mar 2023 10:09:22 +0100 Subject: [PATCH] Lighter construction of finite field elements from lists When doing intensive polynomial arithmetic with the NTL implementation the constructor with lists is called a large number of times and may spend a lot of time constructing the vector_space and FreeModuleElement objects. The very common call to vector_space(map=False) is optimized to be as cheap as possible using the already cached object. The common case of lists of length 0 and 1 is replaced by cheaper shortcuts. --- src/sage/rings/finite_rings/element_pari_ffelt.pyx | 14 +++++++++++++- src/sage/rings/finite_rings/finite_field_base.pyx | 9 +++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/sage/rings/finite_rings/element_pari_ffelt.pyx b/src/sage/rings/finite_rings/element_pari_ffelt.pyx index be70aa56d39..4c0b02011a8 100644 --- a/src/sage/rings/finite_rings/element_pari_ffelt.pyx +++ b/src/sage/rings/finite_rings/element_pari_ffelt.pyx @@ -270,13 +270,19 @@ cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement): sage: k = FiniteField(3^11, 't', impl='pari_ffelt') sage: k([ 0, 1/2 ]) 2*t + sage: k([ 0, 1/2, 0, 0, 0, 0, 0, 0, 0, -1, 0 ]) + 2*t^9 + 2*t sage: k([ k(0), k(1) ]) t sage: k([ GF(3)(2), GF(3^5,'u')(1) ]) t + 2 sage: R. = PolynomialRing(k) + sage: k([ x/x ]) + 1 sage: k([ R(-1), x/x ]) t + 2 + sage: k([ R(-1), R(0), 0 ]) + 2 Check that zeros are created correctly (:trac:`11685`):: @@ -496,7 +502,13 @@ cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement): self.construct_from(x.constant_coefficient()) elif isinstance(x, list): - if len(x) == self._parent.degree(): + n = len(x) + if n == 0: + self.construct_from(None) + elif n == 1: + Fp = self._parent.base_ring() + self.construct_from(Fp(x[0])) + elif n == self._parent.degree(): self.construct_from(self._parent.vector_space(map=False)(x)) else: Fp = self._parent.base_ring() diff --git a/src/sage/rings/finite_rings/finite_field_base.pyx b/src/sage/rings/finite_rings/finite_field_base.pyx index 06e57a04952..fa9c8862ddb 100644 --- a/src/sage/rings/finite_rings/finite_field_base.pyx +++ b/src/sage/rings/finite_rings/finite_field_base.pyx @@ -1230,8 +1230,6 @@ cdef class FiniteField(Field): sage: all(to_V(h(c) * e) == c * to_V(e) for e in E for c in F) True """ - from sage.modules.all import VectorSpace - from sage.categories.morphism import is_Morphism if subfield is not None: if base is not None: raise ValueError @@ -1241,6 +1239,13 @@ cdef class FiniteField(Field): deprecation(28481, "The default value for map will be changing to True. To keep the current behavior, explicitly pass map=False.") map = False + if base is None and self.__vector_space is not None and not map: + # A very common case: return as early as possible. + return self.__vector_space + + from sage.modules.all import VectorSpace + from sage.categories.morphism import is_Morphism + if base is None: base = self.prime_subfield() s = self.degree()