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