[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Faster Prime class then Ruby 1.9

Phil Duby

2/3/2006 7:18:00 AM

Hi all,

I have been playing with my implementation or the Prime class since the my
previous thread where Antonio Cangiano provided the new and improved Ruby
1.9 version of mathn.rb. Once I understood the new version, I found it to
be very close to the base version of my implentation. I did find a simple
way to make it significantly (over 8 times) faster. The Prime#succ method
uses the following line to check a number, and add it to the list if it is a
prime number.

@@primes.push @@next_to_check if @@primes[2..@@ulticheck_index].find
{|prime| @@next_to_check % prime == 0 }.nil?

I noticed that that creates a new sub array @@primes[2..@@ulticheck_index]
every time. Simply extracting that out to another class variable array that
gets one entry added to it every time ulticheck_index is incremented dropped
the time to get 100,000 prime numbers from 377 seconds to 46.3 seconds. I
have made a few other adjustments to implement a method of skipping more
non-prime numbers without having to test each case. The existing Ruby 1.9
version only checks 2 out of 6 numbers (1 and 5 for N modulo 6, step size of
4 and 2). I have it setup to that it skips more numbers using higher
modulos (6 = 2*3 = first 2 primes; I use more primes to get the product
value).

As is, the code rebuilds the list of step sizes when the mathn.rb file is
initially required. That introduces a startup penalty that becomes
noticable in the benchmarks when 5 primes are used. At 7 primes it becomes
significant (4 seconds). Even with that overhead included, the 7 primes
case is faster at getting 100,000 primes than any of the others I have tried
(I did not try 8 primes).

The step size calculation code could be moved to the initialize method, to
delay that startup cost until the first prime is calculated. For lists
based on products of less than about 6 prime numbers, the calculation can be
replaced by hard-coded lists. The product for 5 primes is 2310, and the
list of step sizes is 480 elements long. For 6 primes the product is 30030,
and the list of step sizes jumps to 5760 elements.

Perhaps someone will see a more efficient way of creating that step size
list. I did not spend too much time on it, once I found a fairly clean
'Ruby' way of building it. It does not seem to be worth it to make the list
much bigger. The improvements I get by increasing it are fairly small.
Going from the initial adjustment that got to 46.3 seconds, to a version
that uses an array of 2 step values increased the time to 48.4 seconds.
Increasing the number of primes used in the product to 3,4,5,6,7 changed the
time to 46.6, 44.8, 44.1, 43.0, 42,4 seconds. All times are in seconds to
get 100,008 prime numbers on my 1Ghz Windows XP Pro with 512M. All times
include the require line to load the Prime class (not the full mathn). More
improvement is possible if the step array can be created more efficiently.
That final 42.4 second value includes almost 4 seconds of overhead to build
the array.

Here are the times to get the first 50 prime numbers :: mostly the time for
the require, which includes the step size array initialization. version 2b
uses 2 primes to calculate the product, then calculates the step sizes. 3b,
4b, 5b, 6b, 7b each used one more prime number in the product.
Starting Prime number search benchmark script for mathn_1p9_2b
user system total
real
mathn_1p9_2b: 1 to 50 0.016000 0.000000 0.016000 (
0.016000)
mathn_1p9_3b: 1 to 50 0.000000 0.016000 0.016000 (
0.016000)
mathn_1p9_4b: 1 to 50 0.000000 0.016000 0.016000 (
0.015000)
mathn_1p9_5b: 1 to 50 0.016000 0.016000 0.032000 (
0.032000)
mathn_1p9_6b: 1 to 50 0.219000 0.015000 0.234000 (
0.234000)
mathn_1p9_7b: 1 to 50 3.906000 0.032000 3.938000 (
3.938000)

Here are the changes to the Prime class. This shows the version that uses 7
prime numbers in the product, but all that needs to change for the other
cases, is to change the initial list of prime numbers. Everything else is
calculated from that. I only made changes to the class variables and the
succ method. Unchanged methods not included here.

#
# Modified Prime class from Ruby 1.9 mathn.rb -
# by H. Phil Duby (PHrienDly Computer Consulting, Ltd.)
#

class Prime
include Enumerable
# These are included as class variables to cache them for later uses. If
memory
# usage is a problem, they can be put in Prime#initialize as instance
variables.

@@primes = [2, 3, 5, 7, 11, 13, 17]
@@ulticheck_index = @@primes.size - 1
@@ulticheck_next_squared = @@primes[@@ulticheck_index] ** 2
@@root_primes = []

prd = @@primes.inject( 1 ) { |p, n| p * n } # product of first few prime
numbers
prime_filter = [ * @@primes.last .. prd + 1 ] # list of numbers modulo prd
that
# could be prime numbers
@@primes.each { |p| prime_filter.delete_if { |n| n % p == 0 }} #remove all
of
# numbers in the initial filter that are multiples of the prime
numbers that
# are factors of the calculated product.
accum = 1; @@skip_known = prime_filter.map { |n| ( accum, x = n, n -
accum ).last }
# create step sizes to skip values that are known to be multiples of
the factors
# of the product of the first few prime numbers. This starts from
prd * <n> + 1
# The sum of the step sizes equals prd, so the steps can be used
continiously
# in a circular manner.
# The above steps to calculate @@skip_known can be replaced by hard-code
initilization
# of the step values. Here are the values to use that match the first few
products.
=begin
@@skip_known = [ 2 ] # one prime, product = 2
@@skip_known = [ 4, 2 ] # two primes, product = 6
@@skip_known = [ 6, 4, 2, 4, 2, 4, 6, 2 ] # three primes, product = 30
@@skip_known = [ 10, 2, 4, 2, 4, 6, 2, 6, 4, 2, 4, 6, 6, 2, 6, 4, 2, 6, 4,
6, 8,
4, 2, 4, 2, 4, 8, 6, 4, 6, 2, 4, 6, 2, 6, 6, 4, 2, 4, 6, 2, 6, 4, 2, 4,
2, 10, 2 ]
# # four primes, product = 210
=end
class << @@skip_known #provide method for getting next step size in
infinite circle.
@@skip_i = @@skip_known.size - 1
@@skip_n = [ * 1 .. @@skip_i ] << 0
def next # sequence through the offsets needed to skip the known prime
multiples
return self.at( @@skip_i = @@skip_n.at( @@skip_i )) #circular indexing
end #def next
end #class << @@skip_known
@@next_to_check = 1 #+ @@skip_known.next will get to first possible prime
after
# @@primes[@@ulticheck_index]

def succ
@index += 1
while @index >= @@primes.length
# Only check for prime factors up to the square root of the potential
primes,
# but without the performance hit of an actual square root
calculation.
@@next_to_check += @@skip_known.next
if @@next_to_check >= @@ulticheck_next_squared
@@ulticheck_index += 1
@@root_primes.push @@primes.at(@@ulticheck_index)
@@ulticheck_next_squared = @@primes.at(@@ulticheck_index + 1) ** 2
end
@@primes.push @@next_to_check if @@root_primes.find {|prime|
@@next_to_check % prime == 0 }.nil?
end
return @@primes[@index]
end
alias next succ
end

--
Phil
remove all of the (at)'s to send email



10 Answers

Yoorghis

8/22/2011 4:23:00 AM

0

On Sun, 21 Aug 2011 19:57:48 -0500, Neolibertarian
<cognac756@gmail.com> wrote:

>The curve indicates that as wealth expands, it reaches into everyone's
>lives. Even into indolent lives like your own.

That's nonsense

The only reason why wealth "reached everyones lives" was because the
laws allowed bargaining by labor.

The government FINALLY got off it's ass in the 30's and began the
reformation of it's relationship to the people in the society it
represented.

Loonytarian crap, which apparantly you've decided fulfills some la-la
land universe, was proven to be the shitstain on America

Yoorghis

8/22/2011 4:28:00 AM

0

On Sun, 21 Aug 2011 19:58:21 -0500, Neolibertarian
<cognac756@gmail.com> wrote:

>In article <g6m257hh4thpi84ch8sq5g9o7ju8351b2j@4ax.com>,
> Yoorghis@Jurgis.net wrote:
>
>> On Sun, 21 Aug 2011 10:19:48 -0500, Neolibertarian
>> <cognac756@gmail.com> wrote:
>>
>> >> The matter of quality of life is related to it. Disease, dangerous
>> >> products, employers exploitaton, bad food, water, no health care,
>> >> little education couldnt be altered.
>> >
>> >They were altered.
>>
>>
>> By government
>
>By wealth. Government can't create wealth. It can only tax it.

Government, by laws, allowed the rise of the middle class

The laws that gave rights to labor was the reason why the middle class
evolved.

The laws that regulated money, power, businesses and wealth--finally
curtailed their long-standing strangle hold on society.

The redistribution of wealth via taxation insured that the wealth
didn't end up making a few so fucking wealthy that the nation's
economic division made revolution an option

Which, BTW, was a viable threat in the 20's when conditions here in
americ were so horrible. The marxist rhetoric was looking like an
option to stop the direction we were going.

No, government doesn't produce

But it can shape the system so that the wealth is fairly distributed.

Yoorghis

8/22/2011 4:30:00 AM

0

On Sun, 21 Aug 2011 20:24:54 -0500, Neolibertarian
<cognac756@gmail.com> wrote:

>
>I'm aware that there's a Fox News Channel on Cable/Satellite TV. I've
>even watched it a few times.

Apparantly, you're not aware you nonsense is as ridiculous as theirs.

Your name is an indication that you can't have much historical
educatin.

Yoorghis

8/22/2011 4:32:00 AM

0

On Sun, 21 Aug 2011 20:28:36 -0500, Neolibertarian
<cognac756@gmail.com> wrote:

>> TO make their beliefs sound more plausible, legitimize something not
>> necessarily truth, and make themselves feel good
>
>Your view of humanity reflects poorly, not on humanity, but upon /you/.
>>

My view of the human condition is reflected in the historical record
of what happened to America when government was "small" and had the
attributes that loonytarian idiots propose would (once again) be a
good thing.

Yoorghis

8/22/2011 4:35:00 AM

0

On Sun, 21 Aug 2011 20:28:36 -0500, Neolibertarian
<cognac756@gmail.com> wrote:

>
>Neither Rupert Murdoch nor George Soros have any power you don't freely
>give them.

Murdoch propagates the Republican propaganda line. Scaife, a loony
billionaire finances the think tanks of the Republican party and feed
them policy.

Soros's "contribution" to the scheme of things in relation to Murdoch
and Scaife isn't even a Percent.

And Soros has no official Position in Democratic politics like Scaife
does at CPAC and the republican party

Yoorghis

8/22/2011 4:37:00 AM

0

On Sun, 21 Aug 2011 20:33:27 -0500, Neolibertarian
<cognac756@gmail.com> wrote:

>> Regullatory power of government to protect or coerce to stop inimical
>> behavior serves us VERY well.
>
>[citation needed]

Busted monopolies

Introduced regulatory agencies and power to enforce

Allowed tax law to produce "incentives" to investor class

Directly affected the safety of products, goods and services by laws
and regulatory powers.

Bob

8/22/2011 1:10:00 PM

0

<Yoorghis@Jurgis.net> wrote in message
news:2nl257hu5p06s0e9l2sbkkvub0fk1244du@4ax.com...
> On Sun, 21 Aug 2011 10:19:48 -0500, Neolibertarian
> <cognac756@gmail.com> wrote:
>
>>>
>>> Your silly use of the word "statism" don't make a fucking thing more
>>> than laughable.
>>
>>It's a noun. Generally defined as: "the principle or policy of
>>concentrating extensive economic, political, and related controls in the
>>state at the cost of individual liberty."
>
> Regullatory power of government to protect or coerce to stop inimical
> behavior serves us VERY well.
>
> Unregulated power and wealth, coupled with market capitalism was an
> experiment which eventually collapsed this nation.
>
> AFTER government "grew"---so did the middle class, the entire national
> economic structure, and reached great heights
>
> Loonytarian nonsense was a failure.

Karl would be proud of you.


pete10016

8/22/2011 2:53:00 PM

0

According to the IRS only the rich pay federal income taxes. The
bottom half pay NO taxes at all. Also:

86% of all taxes are paid by the top 25%
39% are paid by the top 1% (up 2% from when Bush took office)

BTW, the median family income is closer to $45,000, or slightly higher.
The median income is much higher than $12,000, that is lower than the
POVERTY line, not the average line!!

Finally, people who argue senselessly against the numbers also confuse
INCOME with WEALTH. Federal income taxes are about income.

-Pete

Yoorghis

8/22/2011 4:29:00 PM

0

On Mon, 22 Aug 2011 08:10:08 -0500, "Bob" <dalnetbob@att.net> wrote:

>> Unregulated power and wealth, coupled with market capitalism was an
>> experiment which eventually collapsed this nation.
>>
>> AFTER government "grew"---so did the middle class, the entire national
>> economic structure, and reached great heights
>>
>> Loonytarian nonsense was a failure.
>
>Karl would be proud of you.
>

I don't know

You provided no objection to the major cause of the rise of the middle
class, only evoking some juvenile reference.

FYI, the primary whine and moan of your fellow
consevative/loonytarians/republicans is that the failure of a small
class of people (for various reasons) who don't "work"

a) the wealth class inheritors don't have to work, they get millions
(even billions) by simply being born

b) the mantra of the Republican party has been to scapegoat the
"welfarte class"---

c) The Marxist dictum: "He who does not work, shall not eat" is the
GOP mantra paraphrased.

Sid9

8/22/2011 4:32:00 PM

0


"pete10016" <pete10016@nospamplease.com> wrote in message
news:KIidnSMjzLHg8M_TnZ2dnUVZ_sKdnZ2d@giganews.com...
> According to the IRS only the rich pay federal income taxes. The bottom
> half pay NO taxes at all. Also:
>
> 86% of all taxes are paid by the top 25%
> 39% are paid by the top 1% (up 2% from when Bush took office)
>
> BTW, the median family income is closer to $45,000, or slightly higher.
> The median income is much higher than $12,000, that is lower than the
> POVERTY line, not the average line!!
>
> Finally, people who argue senselessly against the numbers also confuse
> INCOME with WEALTH. Federal income taxes are about income.
>
> -Pete
>

This aggregation of income tax is deceptive.
The measure should be the burden on the tax payer.
The burden on wealthy taxpayers is much less then on middle class taxpayers.
That's why Obama's approach to rescinding bush,jr tax cuts on thos earning
over $250,000 makes sense