summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Llorens <daniel.llorens@bluewin.ch>2013-04-19 14:53:34 +0200
committerAndy Wingo <wingo@pobox.com>2014-02-07 15:46:03 +0100
commit0e5c6f5ae96f19e9941f8068b83918a8f0a26744 (patch)
treeeebfec3f5f7f96f7dd485efb496c06c39cc66950
parentcde8b37582288b7e0c2bde14cf0b76b88198f084 (diff)
downloadguile-0e5c6f5ae96f19e9941f8068b83918a8f0a26744.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.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/libguile/array-map.c b/libguile/array-map.c
index c38ed726b..7c3028643 100644
--- a/libguile/array-map.c
+++ b/libguile/array-map.c
@@ -328,6 +328,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)
{
@@ -337,16 +340,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);