1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-02 13:00:26 +02:00

Raw pointer loop in array-copy! for vector/vector case

This special case improves

(define a (make-array 1. 1000000 10))
(define b (make-array *unspecified* 1000000 10))
(define c (transpose-array (make-array *unspecified* 10 1000000) 1 0))
,time (array-copy! a b)
,time (array-copy! a c)

from 0.041598s / 0.072561 to 0.012164s / 0.041886s on a i7-3930K.

* libguile/array-map.c: (racp): if both src and dst are on vectors, use
  the element pointers to do the copy.
This commit is contained in:
Daniel Llorens 2013-04-19 14:53:34 +02:00 committed by Andy Wingo
parent 8190effae2
commit 4552a0c406

View file

@ -341,6 +341,9 @@ SCM_DEFINE (scm_array_fill_x, "array-fill!", 2, 0, 0,
#undef FUNC_NAME #undef FUNC_NAME
/* FIXME src-dst is the wrong order for scm_ra_matchp, but scm_ramapc
doesn't send SCM_I_ARRAYP for both src and dst, and this segfaults
with the 'right' order. */
static int static int
racp (SCM src, SCM dst) racp (SCM src, SCM dst)
{ {
@ -350,16 +353,24 @@ racp (SCM src, SCM dst)
ssize_t inc_s, inc_d; ssize_t inc_s, inc_d;
dst = SCM_CAR (dst); dst = SCM_CAR (dst);
scm_array_get_handle (SCM_I_ARRAY_V (src), &h_s);
scm_array_get_handle (SCM_I_ARRAY_V (dst), &h_d);
i_s = SCM_I_ARRAY_BASE (src); i_s = SCM_I_ARRAY_BASE (src);
i_d = SCM_I_ARRAY_BASE (dst); i_d = SCM_I_ARRAY_BASE (dst);
inc_s = SCM_I_ARRAY_DIMS (src)->inc; inc_s = SCM_I_ARRAY_DIMS (src)->inc;
inc_d = SCM_I_ARRAY_DIMS (dst)->inc; inc_d = SCM_I_ARRAY_DIMS (dst)->inc;
for (; n-- > 0; i_s += inc_s, i_d += inc_d) scm_array_get_handle (SCM_I_ARRAY_V (src), &h_s);
h_d.impl->vset (SCM_I_ARRAY_V (dst), i_d, h_s.impl->vref (SCM_I_ARRAY_V (src), i_s)); scm_array_get_handle (SCM_I_ARRAY_V (dst), &h_d);
if (scm_is_vector (SCM_I_ARRAY_V (src)) && scm_is_vector (SCM_I_ARRAY_V (dst)))
{
SCM const * el_s = h_s.elements;
SCM * el_d = h_d.writable_elements;
for (; n-- > 0; i_s += inc_s, i_d += inc_d)
el_d[i_d] = el_s[i_s];
}
else
for (; n-- > 0; i_s += inc_s, i_d += inc_d)
h_d.impl->vset (SCM_I_ARRAY_V (dst), i_d, h_s.impl->vref (SCM_I_ARRAY_V (src), i_s));
scm_array_handle_release (&h_d); scm_array_handle_release (&h_d);
scm_array_handle_release (&h_s); scm_array_handle_release (&h_s);