[libmath-prime-util-perl] 06/18: Very small optimization for PrimeArray.

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


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

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

commit e865e450c569b9250a5c786729022db7c64aa656
Author: Dana Jacobsen <dana at acm.org>
Date:   Sat Dec 15 23:55:50 2012 -0800

    Very small optimization for PrimeArray.
---
 lib/Math/Prime/Util/PrimeArray.pm | 51 ++++++++++++++++++++++++++-------------
 1 file changed, 34 insertions(+), 17 deletions(-)

diff --git a/lib/Math/Prime/Util/PrimeArray.pm b/lib/Math/Prime/Util/PrimeArray.pm
index a8002ed..76d7adc 100644
--- a/lib/Math/Prime/Util/PrimeArray.pm
+++ b/lib/Math/Prime/Util/PrimeArray.pm
@@ -34,6 +34,8 @@ sub TIEARRAY {
     BEG_INDEX  => 0,
     # What's the index of the last one?
     END_INDEX  => 6,
+    # positive = forward, negative = backward, 0 = random
+    ACCESS_TYPE => 0,
   }, $class;
 }
 sub STORE     { carp "You cannot write to the prime array"; }
@@ -45,30 +47,45 @@ sub EXTEND    { 1 }
 sub FETCHSIZE { 0x7FFF_FFFF }   # Even on 64-bit
 # Simple FETCH:
 # sub FETCH { return nth_prime($_[1]+1); }
+
 sub FETCH {
   my $self = shift;
   my $index = shift;
   # We actually don't get negative indices -- they get turned into big numbers
   croak "Negative index given to prime array" if $index < 0;
   $index += $self->{SHIFTINDEX};  # take into account any shifts
-  if ( ($index < $self->{BEG_INDEX}) || ($index > $self->{END_INDEX}) ) {
-    # We're going to get a chunk of primes starting 1000 before the one
-    # asked for, and extending at _least_ 1000 past it.  So given a number
-    # past index 1000, we would expect to have ~2000 primes with the one
-    # requested being about in the middle.  This should be reasonably fast
-    # for the siever and amortize the cost over a lot of calls if they're
-    # walking us.  Yes, we'll get well over 2000 primes as the numbers get
-    # very large, but that's ok (e.g. 80k primes at index 400M).  Calling
-    # nth_prime on indices that large is very time consuming.
-    my $start_idx = ($index < 1000) ? 0 : $index-1000;
-    my $start_prime = nth_prime($start_idx+1);       # This is exact
-    my $end_prime   = nth_prime_upper($index+5000);  # This is a bound
-    #print "calling primes from $start_idx/$start_prime to $end_prime\n";
-    $self->{PRIMES} = primes($start_prime, $end_prime);
-    $self->{BEG_INDEX} = $start_idx;
-    $self->{END_INDEX} = $start_idx + scalar @{$self->{PRIMES}} - 1;;
+  my $begidx = $self->{BEG_INDEX};
+  my $endidx = $self->{END_INDEX};
+
+  if ( $index < $begidx || $index > $endidx ) {
+
+    if    ($index == $endidx+1) { $self->{ACCESS_TYPE}++; }
+    elsif ($index == $begidx-1) { $self->{ACCESS_TYPE}--; }
+    else                        { $self->{ACCESS_TYPE}=0; }
+
+    if ($index == $endidx+1  &&  $self->{ACCESS_TYPE} > 2) {  # Forward iter
+
+      my $end_prime = nth_prime_upper($index + 10000);
+      $self->{PRIMES} = primes( $self->{PRIMES}->[-1]+1, $end_prime );
+
+      $begidx = $endidx+1;
+
+    # TODO: backwards iter
+
+    } else {  # Looks like random access so far.  Get a small range.
+
+      my $start_idx = ($index < 500) ? 0 : $index - 500;
+      my $start_prime = nth_prime($start_idx+1);       # This is exact
+      my $end_prime   = nth_prime_upper($index+500);   # This is a bound
+      $self->{PRIMES} = primes($start_prime, $end_prime);
+
+      $begidx = $start_idx;
+
+    }
+    $self->{BEG_INDEX} = $begidx;
+    $self->{END_INDEX} = $begidx + scalar @{$self->{PRIMES}} - 1;
   }
-  return $self->{PRIMES}->[ $index - $self->{BEG_INDEX} ];
+  return $self->{PRIMES}->[ $index - $begidx ];
 }
 
 # Fake out shift and unshift

-- 
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