[libmath-prime-util-perl] 111/181: Refactor forprimes

Partha P. Mukherjee ppm-guest at moszumanska.debian.org
Thu May 21 18:51:12 UTC 2015


This is an automated email from the git hooks/post-receive script.

ppm-guest pushed a commit to annotated tag v0.36
in repository libmath-prime-util-perl.

commit 7fd13a88adf1bd5cfda9b9652af18f532bc7429f
Author: Dana Jacobsen <dana at acm.org>
Date:   Sat Jan 4 00:54:55 2014 -0800

    Refactor forprimes
---
 XS.xs | 104 +++++++++++++++++++++++++++++-------------------------------------
 1 file changed, 46 insertions(+), 58 deletions(-)

diff --git a/XS.xs b/XS.xs
index bc31566..2cae867 100644
--- a/XS.xs
+++ b/XS.xs
@@ -839,24 +839,23 @@ _validate_num(SV* svn, ...)
 void
 forprimes (SV* block, IN SV* svbeg, IN SV* svend = 0)
   PROTOTYPE: &$;$
-  PPCODE:
-  {
-#if !USE_MULTICALL
-    _vcallsubn(aTHX_ G_VOID|G_DISCARD, 0, "_generic_forprimes", items);
-#else
-    UV beg, end;
+  PREINIT:
     GV *gv;
     HV *stash;
+    SV* svarg;
     CV *cv;
-    SV* svarg;  /* We use svarg to prevent clobbering $_ outside the block */
-    void* ctx;
     unsigned char* segment;
-    UV seg_base, seg_low, seg_high;
+    UV beg, end, seg_base, seg_low, seg_high;
+  PPCODE:
+    cv = sv_2cv(block, &stash, &gv, 0);
+    if (cv == Nullcv)
+      croak("Not a subroutine reference");
 
     if (!_validate_int(aTHX_ svbeg, 0) || (items >= 3 && !_validate_int(aTHX_ svend,0))) {
       _vcallsubn(aTHX_ G_VOID|G_DISCARD, 0, "_generic_forprimes", items);
       return;
     }
+
     if (items < 3) {
       beg = 2;
       end = my_svuv(svbeg);
@@ -864,12 +863,7 @@ forprimes (SV* block, IN SV* svbeg, IN SV* svend = 0)
       beg = my_svuv(svbeg);
       end = my_svuv(svend);
     }
-    if (beg > end)
-      XSRETURN(0);
 
-    cv = sv_2cv(block, &stash, &gv, 0);
-    if (cv == Nullcv)
-      croak("Not a subroutine reference");
     SAVESPTR(GvSV(PL_defgv));
     svarg = newSVuv(0);
     GvSV(PL_defgv) = svarg;
@@ -883,63 +877,61 @@ forprimes (SV* block, IN SV* svbeg, IN SV* svend = 0)
       }
       beg += 1 + (beg > 2);
     }
-    /* For small ranges with large bases or tiny ranges, it will be faster
-     * and less memory to just iterate through the primes in range.  The
-     * exact limits will change based on the sieve vs. next_prime speed. */
-    if (beg <= end && !CvISXSUB(cv) && (
+#if USE_MULTICALL
+    if (!CvISXSUB(cv) && beg <= end) {
+      dMULTICALL;
+      I32 gimme = G_VOID;
+      PUSH_MULTICALL(cv);
+      if (
 #if BITS_PER_WORD == 64
           (beg >= UVCONST(     100000000000000) && end-beg <    100000) ||
           (beg >= UVCONST(      10000000000000) && end-beg <     40000) ||
           (beg >= UVCONST(       1000000000000) && end-beg <     17000) ||
 #endif
-          (                                        end-beg <       500) ) ) {
-      dMULTICALL;
-      I32 gimme = G_VOID;
-      PUSH_MULTICALL(cv);
-      for (beg = _XS_next_prime(beg-1); beg <= end && beg != 0; beg = _XS_next_prime(beg)) {
-        sv_setuv(svarg, beg);
-        MULTICALL;
-      }
-      FIX_MULTICALL_REFCOUNT;
-      POP_MULTICALL;
-    } else if (beg <= end) {
-      ctx = start_segment_primes(beg, end, &segment);
-      while (next_segment_primes(ctx, &seg_base, &seg_low, &seg_high)) {
-        if (!CvISXSUB(cv)) {
-          dMULTICALL;
-          I32 gimme = G_VOID;
-          PUSH_MULTICALL(cv);
+          ((end-beg) < 500) ) {     /* MULTICALL next prime */
+        for (beg = _XS_next_prime(beg-1); beg <= end && beg != 0; beg = _XS_next_prime(beg)) {
+          sv_setuv(svarg, beg);
+          MULTICALL;
+        }
+      } else {                      /* MULTICALL segment sieve */
+        void* ctx = start_segment_primes(beg, end, &segment);
+        while (next_segment_primes(ctx, &seg_base, &seg_low, &seg_high)) {
           START_DO_FOR_EACH_SIEVE_PRIME( segment, seg_low - seg_base, seg_high - seg_base ) {
             sv_setuv(svarg, seg_base + p);
             MULTICALL;
           } END_DO_FOR_EACH_SIEVE_PRIME
-          FIX_MULTICALL_REFCOUNT;
-          POP_MULTICALL;
-        } else {
-          START_DO_FOR_EACH_SIEVE_PRIME( segment, seg_low - seg_base, seg_high - seg_base ) {
-            sv_setuv(svarg, seg_base + p);
-            PUSHMARK(SP);
-            call_sv((SV*)cv, G_VOID|G_DISCARD);
-          } END_DO_FOR_EACH_SIEVE_PRIME
         }
+        end_segment_primes(ctx);
+      }
+      FIX_MULTICALL_REFCOUNT;
+      POP_MULTICALL;
+    }
+    else
+#endif
+    if (beg <= end) {               /* NO-MULTICALL segment sieve */
+      void* ctx = start_segment_primes(beg, end, &segment);
+      while (next_segment_primes(ctx, &seg_base, &seg_low, &seg_high)) {
+        START_DO_FOR_EACH_SIEVE_PRIME( segment, seg_low - seg_base, seg_high - seg_base ) {
+          sv_setuv(svarg, seg_base + p);
+          PUSHMARK(SP);
+          call_sv((SV*)cv, G_VOID|G_DISCARD);
+        } END_DO_FOR_EACH_SIEVE_PRIME
       }
       end_segment_primes(ctx);
     }
     SvREFCNT_dec(svarg);
-#endif
-  }
 
 void
 forcomposites (SV* block, IN SV* svbeg, IN SV* svend = 0)
   PROTOTYPE: &$;$
-  PPCODE:
-  {
+  PREINIT:
     UV beg, end;
     GV *gv;
     HV *stash;
     SV* svarg;  /* We use svarg to prevent clobbering $_ outside the block */
-    CV *cv = sv_2cv(block, &stash, &gv, 0);
-
+    CV *cv;
+  PPCODE:
+    cv = sv_2cv(block, &stash, &gv, 0);
     if (cv == Nullcv)
       croak("Not a subroutine reference");
 
@@ -955,8 +947,6 @@ forcomposites (SV* block, IN SV* svbeg, IN SV* svend = 0)
       beg = my_svuv(svbeg);
       end = my_svuv(svend);
     }
-    if (beg > end)
-      return;
 
     SAVESPTR(GvSV(PL_defgv));
     svarg = newSVuv(0);
@@ -995,7 +985,7 @@ forcomposites (SV* block, IN SV* svbeg, IN SV* svend = 0)
     }
     else
 #endif
-    {
+    if (beg <= end) {
       beg = (beg <= 4) ? 3 : beg-1;
       while (beg++ < end) {
         if (!_XS_is_prob_prime(beg)) {
@@ -1006,20 +996,19 @@ forcomposites (SV* block, IN SV* svbeg, IN SV* svend = 0)
       }
     }
     SvREFCNT_dec(svarg);
-  }
 
 void
 fordivisors (SV* block, IN SV* svn)
   PROTOTYPE: &$
-  PPCODE:
-  {
+  PREINIT:
     UV i, n, ndivisors;
     UV *divs;
     GV *gv;
     HV *stash;
     SV* svarg;  /* We use svarg to prevent clobbering $_ outside the block */
-    CV *cv = sv_2cv(block, &stash, &gv, 0);
-
+    CV *cv;
+  PPCODE:
+    cv = sv_2cv(block, &stash, &gv, 0);
     if (cv == Nullcv)
       croak("Not a subroutine reference");
 
@@ -1057,4 +1046,3 @@ fordivisors (SV* block, IN SV* svn)
     }
     SvREFCNT_dec(svarg);
     Safefree(divs);
-  }

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-perl/packages/libmath-prime-util-perl.git



More information about the Pkg-perl-cvs-commits mailing list