Changeset: c1bd83558575 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=c1bd83558575
Modified Files:
        gdk/gdk_aggr.c
        gdk/gdk_calc_private.h
Branch: default
Log Message:

Speed up aggr.sum for most "normal" cases.


diffs (243 lines):

diff --git a/gdk/gdk_aggr.c b/gdk/gdk_aggr.c
--- a/gdk/gdk_aggr.c
+++ b/gdk/gdk_aggr.c
@@ -153,48 +153,157 @@ BATgroupaggrinit(const BAT *b, const BAT
 
 #define AGGR_SUM(TYPE1, TYPE2)                                         \
        do {                                                            \
+               TYPE1 x;                                                \
                const TYPE1 *vals = (const TYPE1 *) values;             \
-               for (i = start; i < end; i++, vals++) {                 \
-                       if (cand) {                                     \
+               if (ngrp == 1 && cand == NULL) {                        \
+                       TYPE2 sum;                                      \
+                       int seenval;                                    \
+                       ALGODEBUG fprintf(stderr,                       \
+                                         "#%s: no candidates, no groups; " \
+                                         "start " BUNFMT ", end " BUNFMT \
+                                         ", nonil = %d\n",             \
+                                         func, start, end, nonil);     \
+                       sum = 0;                                        \
+                       if (nonil) {                                    \
+                               seenval = start > end;                  \
+                               for (i = start; i < end && nils == 0; i++, 
vals++) { \
+                                       x = *vals;                      \
+                                       ADD_WITH_CHECK(TYPE1, x,        \
+                                                      TYPE2, sum,      \
+                                                      TYPE2, sum,      \
+                                                      goto overflow);  \
+                               }                                       \
+                       } else {                                        \
+                               seenval = 0;                            \
+                               for (i = start; i < end && nils == 0; i++, 
vals++) { \
+                                       x = *vals;                      \
+                                       if (x == TYPE1##_nil) {         \
+                                               if (!skip_nils) {       \
+                                                       sum = TYPE2##_nil; \
+                                                       nils = 1;       \
+                                               }                       \
+                                       } else {                        \
+                                               ADD_WITH_CHECK(TYPE1, x, \
+                                                              TYPE2, sum, \
+                                                              TYPE2, sum, \
+                                                              goto overflow); \
+                                               seenval = 1;            \
+                                       }                               \
+                               }                                       \
+                       }                                               \
+                       if (seenval)                                    \
+                               *sums = sum;                            \
+               } else if (ngrp == 1) {                                 \
+                       TYPE2 sum;                                      \
+                       int seenval = 0;                                \
+                       ALGODEBUG fprintf(stderr,                       \
+                                         "#%s: with candidates, no groups; " \
+                                         "start " BUNFMT ", end " BUNFMT \
+                                         "\n",                         \
+                                         func, start, end);            \
+                       sum = 0;                                        \
+                       for (i = start; i < end && nils == 0; i++, vals++) { \
                                if (i < *cand - seqb) {                 \
-                                       if (gids)                       \
-                                               gids += gidincr;        \
                                        continue;                       \
                                }                                       \
                                assert(i == *cand - seqb);              \
                                if (++cand == candend)                  \
                                        end = i + 1;                    \
-                       }                                               \
-                       if (gids == NULL || gidincr == 0 ||             \
-                           (*gids >= min && *gids <= max)) {           \
-                               gid = gids ? *gids - min : (oid) i;     \
-                               if (nil_if_empty &&                     \
-                                   !(seen[gid >> 5] & (1 << (gid & 0x1F)))) { \
-                                       seen[gid >> 5] |= 1 << (gid & 0x1F); \
-                                       sums[gid] = 0;                  \
-                               }                                       \
-                               if (*vals == TYPE1##_nil) {             \
+                               x = *vals;                              \
+                               if (x == TYPE1##_nil) {                 \
                                        if (!skip_nils) {               \
-                                               sums[gid] = TYPE2##_nil; \
-                                               nils++;                 \
+                                               sum = TYPE2##_nil;      \
+                                               nils = 1;               \
                                        }                               \
-                               } else if (sums[gid] != TYPE2##_nil) {  \
-                                       ADD_WITH_CHECK(TYPE1, *vals,    \
-                                                      TYPE2, sums[gid], \
-                                                      TYPE2, sums[gid], \
+                               } else {                                \
+                                       ADD_WITH_CHECK(TYPE1, x,        \
+                                                      TYPE2, sum,      \
+                                                      TYPE2, sum,      \
                                                       goto overflow);  \
+                                       seenval = 1;                    \
                                }                                       \
                        }                                               \
-                       if (gids)                                       \
-                               gids += gidincr;                        \
+                       if (seenval)                                    \
+                               *sums = sum;                            \
+               } else if (cand == NULL) {                              \
+                       ALGODEBUG fprintf(stderr,                       \
+                                         "#%s: no candidates, with groups; " \
+                                         "start " BUNFMT ", end " BUNFMT \
+                                         "\n",                         \
+                                         func, start, end);            \
+                       for (i = start; i < end; i++, vals++) {         \
+                               if (gids == NULL ||                     \
+                                   (*gids >= min && *gids <= max)) {   \
+                                       gid = gids ? *gids - min : (oid) i; \
+                                       if (nil_if_empty &&             \
+                                           !(seen[gid >> 5] & (1 << (gid & 
0x1F)))) { \
+                                               seen[gid >> 5] |= 1 << (gid & 
0x1F); \
+                                               sums[gid] = 0;          \
+                                       }                               \
+                                       x = *vals;                      \
+                                       if (x == TYPE1##_nil) {         \
+                                               if (!skip_nils) {       \
+                                                       sums[gid] = 
TYPE2##_nil; \
+                                                       nils++;         \
+                                               }                       \
+                                       } else if (sums[gid] != TYPE2##_nil) { \
+                                               ADD_WITH_CHECK(TYPE1, x, \
+                                                              TYPE2, 
sums[gid], \
+                                                              TYPE2, 
sums[gid], \
+                                                              goto overflow); \
+                                       }                               \
+                               }                                       \
+                               if (gids)                               \
+                                       gids++;                         \
+                       }                                               \
+               } else {                                                \
+                       ALGODEBUG fprintf(stderr,                       \
+                                         "#%s: with candidates, with groups; " 
\
+                                         "start " BUNFMT ", end " BUNFMT \
+                                         "\n",                         \
+                                         func, start, end);            \
+                       for (i = start; i < end; i++, vals++) {         \
+                               if (i < *cand - seqb) {                 \
+                                       if (gids)                       \
+                                               gids++;                 \
+                                       continue;                       \
+                               }                                       \
+                               assert(i == *cand - seqb);              \
+                               if (++cand == candend)                  \
+                                       end = i + 1;                    \
+                               if (gids == NULL ||                     \
+                                   (*gids >= min && *gids <= max)) {   \
+                                       gid = gids ? *gids - min : (oid) i; \
+                                       if (nil_if_empty &&             \
+                                           !(seen[gid >> 5] & (1 << (gid & 
0x1F)))) { \
+                                               seen[gid >> 5] |= 1 << (gid & 
0x1F); \
+                                               sums[gid] = 0;          \
+                                       }                               \
+                                       x = *vals;                      \
+                                       if (x == TYPE1##_nil) {         \
+                                               if (!skip_nils) {       \
+                                                       sums[gid] = 
TYPE2##_nil; \
+                                                       nils++;         \
+                                               }                       \
+                                       } else if (sums[gid] != TYPE2##_nil) { \
+                                               ADD_WITH_CHECK(TYPE1, x, \
+                                                              TYPE2, 
sums[gid], \
+                                                              TYPE2, 
sums[gid], \
+                                                              goto overflow); \
+                                       }                               \
+                               }                                       \
+                               if (gids)                               \
+                                       gids++;                         \
+                       }                                               \
                }                                                       \
        } while (0)
 
 static BUN
-dosum(const void *values, oid seqb, BUN start, BUN end, void *results,
-      BUN ngrp, int tp1, int tp2, const oid *cand, const oid *candend,
-      const oid *gids, int gidincr, oid min, oid max,
-      int skip_nils, int abort_on_error, int nil_if_empty, const char *func)
+dosum(const void *values, int nonil, oid seqb, BUN start, BUN end,
+      void *results, BUN ngrp, int tp1, int tp2,
+      const oid *cand, const oid *candend, const oid *gids,
+      oid min, oid max, int skip_nils, int abort_on_error,
+      int nil_if_empty, const char *func)
 {
        BUN nils = 0;
        BUN i;
@@ -376,9 +485,9 @@ BATgroupsum(BAT *b, BAT *g, BAT *e, BAT 
        else
                gids = (const oid *) Tloc(g, BUNfirst(g) + start);
 
-       nils = dosum(Tloc(b, BUNfirst(b)), b->hseqbase, start, end,
+       nils = dosum(Tloc(b, BUNfirst(b)), b->T->nonil, b->hseqbase, start, end,
                     Tloc(bn, BUNfirst(bn)), ngrp, b->ttype, tp,
-                    cand, candend, gids, 1, min, max,
+                    cand, candend, gids, min, max,
                     skip_nils, abort_on_error, 1, "BATgroupsum");
 
        if (nils < BUN_NONE) {
@@ -498,8 +607,8 @@ BATsum(void *res, int tp, BAT *b, BAT *s
        }
        if (BATcount(b) == 0)
                return GDK_SUCCEED;
-       nils = dosum(Tloc(b, BUNfirst(b)), b->hseqbase, start, end, res, 1,
-                    b->ttype, tp, cand, candend, &min, 0, min, max,
+       nils = dosum(Tloc(b, BUNfirst(b)), b->T->nonil, b->hseqbase, start, end,
+                    res, 1, b->ttype, tp, cand, candend, &min, min, max,
                     skip_nils, abort_on_error, nil_if_empty, "BATsum");
        return nils < BUN_NONE ? GDK_SUCCEED : GDK_FAIL;
 }
diff --git a/gdk/gdk_calc_private.h b/gdk/gdk_calc_private.h
--- a/gdk/gdk_calc_private.h
+++ b/gdk/gdk_calc_private.h
@@ -50,9 +50,16 @@ typedef unsigned __int64 ulng;
                        assert(BATttype(s) == TYPE_oid);                \
                        if (BATcount(s) == 0) {                         \
                                start = end = 0;                        \
-                       } else if (BATtdense(s)) {                      \
-                               start = (s)->T->seq;                    \
-                               end = start + BATcount(s);              \
+                       } else {                                        \
+                               if (BATtdense(s)) {                     \
+                                       start = (s)->T->seq;            \
+                                       end = start + BATcount(s);      \
+                               } else {                                \
+                                       cand = (const oid *) Tloc((s), 
BUNfirst(s)); \
+                                       candend = cand + BATcount(s);   \
+                                       start = *cand;                  \
+                                       end = candend[-1] + 1;          \
+                               }                                       \
                                if (start < (b)->H->seq)                \
                                        start = 0;                      \
                                else                                    \
@@ -61,9 +68,6 @@ typedef unsigned __int64 ulng;
                                        end = cnt;                      \
                                else                                    \
                                        end -= (b)->H->seq;             \
-                       } else {                                        \
-                               cand = (const oid *) Tloc((s), BUNfirst(s)); \
-                               candend = cand + BATcount(s);           \
                        }                                               \
                }                                                       \
        } while (0)
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to