summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Harris <charlesr.harris@gmail.com>2023-05-13 10:42:57 -0600
committerGitHub <noreply@github.com>2023-05-13 10:42:57 -0600
commit81caed6e3c34c4bf4b22b4f6167e816ba2a3f73c (patch)
treef20db8326ea5323562351c99c02ed6d4c237e2dd
parent25908cacd19915bf3ddd659c28be28a41bd97a54 (diff)
parent5e983f22c3d554377b0541ff46507001123addca (diff)
downloadnumpy-81caed6e3c34c4bf4b22b4f6167e816ba2a3f73c.tar.gz
Merge pull request #23746 from mattip/scalar-str
ENH: add fast path for str(scalar_int)
-rw-r--r--benchmarks/benchmarks/bench_scalar.py12
-rw-r--r--numpy/core/src/multiarray/scalartypes.c.src38
-rw-r--r--numpy/core/tests/test_arrayprint.py5
3 files changed, 52 insertions, 3 deletions
diff --git a/benchmarks/benchmarks/bench_scalar.py b/benchmarks/benchmarks/bench_scalar.py
index 650daa89d..638f66df5 100644
--- a/benchmarks/benchmarks/bench_scalar.py
+++ b/benchmarks/benchmarks/bench_scalar.py
@@ -65,3 +65,15 @@ class ScalarMath(Benchmark):
other + int32
other + int32
other + int32
+
+
+class ScalarStr(Benchmark):
+ # Test scalar to str conversion
+ params = [TYPES1]
+ param_names = ["type"]
+
+ def setup(self, typename):
+ self.a = np.array([100] * 100, dtype=typename)
+
+ def time_str_repr(self, typename):
+ res = [str(x) for x in self.a]
diff --git a/numpy/core/src/multiarray/scalartypes.c.src b/numpy/core/src/multiarray/scalartypes.c.src
index c721800be..ff30737b5 100644
--- a/numpy/core/src/multiarray/scalartypes.c.src
+++ b/numpy/core/src/multiarray/scalartypes.c.src
@@ -279,7 +279,43 @@ static PyObject *
genint_type_str(PyObject *self)
{
PyObject *item, *item_str;
- item = gentype_generic_method(self, NULL, NULL, "item");
+ PyArray_Descr *descr = PyArray_DescrFromTypeObject((PyObject *)Py_TYPE(self));
+ void *val = scalar_value(self, descr);
+ switch (descr->type_num) {
+ case NPY_BYTE:
+ item = PyLong_FromLong(*(int8_t *)val);
+ break;
+ case NPY_UBYTE:
+ item = PyLong_FromUnsignedLong(*(uint8_t *)val);
+ break;
+ case NPY_SHORT:
+ item = PyLong_FromLong(*(int16_t *)val);
+ break;
+ case NPY_USHORT:
+ item = PyLong_FromUnsignedLong(*(uint16_t *)val);
+ break;
+ case NPY_INT:
+ item = PyLong_FromLong(*(int32_t *)val);
+ break;
+ case NPY_UINT:
+ item = PyLong_FromUnsignedLong(*(uint32_t *)val);
+ break;
+ case NPY_LONG:
+ item = PyLong_FromLong(*(int64_t *)val);
+ break;
+ case NPY_ULONG:
+ item = PyLong_FromUnsignedLong(*(uint64_t *)val);
+ break;
+ case NPY_LONGLONG:
+ item = PyLong_FromLongLong(*(long long *)val);
+ break;
+ case NPY_ULONGLONG:
+ item = PyLong_FromUnsignedLongLong(*(unsigned long long *)val);
+ break;
+ default:
+ item = gentype_generic_method(self, NULL, NULL, "item");
+ break;
+ }
if (item == NULL) {
return NULL;
}
diff --git a/numpy/core/tests/test_arrayprint.py b/numpy/core/tests/test_arrayprint.py
index b92c8ae8c..6796b4077 100644
--- a/numpy/core/tests/test_arrayprint.py
+++ b/numpy/core/tests/test_arrayprint.py
@@ -258,8 +258,7 @@ class TestArray2String:
assert_(np.array2string(s, formatter={'numpystr':lambda s: s*2}) ==
'[abcabc defdef]')
-
- def test_structure_format(self):
+ def test_structure_format_mixed(self):
dt = np.dtype([('name', np.str_, 16), ('grades', np.float64, (2,))])
x = np.array([('Sarah', (8.0, 7.0)), ('John', (6.0, 7.0))], dtype=dt)
assert_equal(np.array2string(x),
@@ -301,6 +300,7 @@ class TestArray2String:
( 'NaT',) ( 'NaT',) ( 'NaT',)]""")
)
+ def test_structure_format_int(self):
# See #8160
struct_int = np.array([([1, -1],), ([123, 1],)], dtype=[('B', 'i4', 2)])
assert_equal(np.array2string(struct_int),
@@ -310,6 +310,7 @@ class TestArray2String:
assert_equal(np.array2string(struct_2dint),
"[([[ 0, 1], [ 2, 3]],) ([[12, 0], [ 0, 0]],)]")
+ def test_structure_format_float(self):
# See #8172
array_scalar = np.array(
(1., 2.1234567890123456789, 3.), dtype=('f8,f8,f8'))