diff options
author | Daniel Llorens <daniel.llorens@bluewin.ch> | 2013-04-19 14:53:34 +0200 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2014-01-27 21:45:54 +0100 |
commit | 4552a0c4068872ad3bf5d8ed27610de7706b3b51 (patch) | |
tree | abb6b9bb47e80e08f2a3e57dfc505dda76924215 | |
parent | 8190effae22e1ad1086fb0cae429ae42ff6f761d (diff) | |
download | guile-4552a0c4068872ad3bf5d8ed27610de7706b3b51.tar.gz |
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.
-rw-r--r-- | libguile/array-map.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/libguile/array-map.c b/libguile/array-map.c index b2c5f4bed..790f5dc00 100644 --- a/libguile/array-map.c +++ b/libguile/array-map.c @@ -341,6 +341,9 @@ SCM_DEFINE (scm_array_fill_x, "array-fill!", 2, 0, 0, #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 racp (SCM src, SCM dst) { @@ -350,16 +353,24 @@ racp (SCM src, SCM dst) ssize_t inc_s, inc_d; 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_d = SCM_I_ARRAY_BASE (dst); inc_s = SCM_I_ARRAY_DIMS (src)->inc; inc_d = SCM_I_ARRAY_DIMS (dst)->inc; - 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_get_handle (SCM_I_ARRAY_V (src), &h_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_s); |