Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #39117 > unrolled thread

Python 3.3 vs. MSDOS Basic

Started byJohn Immarino <johimm@gmail.com>
First post2013-02-18 11:13 -0800
Last post2013-02-19 15:02 +0100
Articles 14 on this page of 34 — 14 participants

Back to article view | Back to comp.lang.python


Contents

  Python 3.3 vs. MSDOS Basic John Immarino <johimm@gmail.com> - 2013-02-18 11:13 -0800
    Re: Python 3.3 vs. MSDOS Basic Chris Angelico <rosuav@gmail.com> - 2013-02-19 08:55 +1100
    Re: Python 3.3 vs. MSDOS Basic Ian Kelly <ian.g.kelly@gmail.com> - 2013-02-18 14:54 -0700
      Re: Python 3.3 vs. MSDOS Basic Tim Daneliuk <tundra@tundraware.com> - 2013-02-19 08:46 -0600
        Re: Python 3.3 vs. MSDOS Basic Ian Kelly <ian.g.kelly@gmail.com> - 2013-02-19 11:31 -0700
          Re: Python 3.3 vs. MSDOS Basic Tim Daneliuk <tundra@tundraware.com> - 2013-02-20 08:21 -0600
            Re: Python 3.3 vs. MSDOS Basic Ian Kelly <ian.g.kelly@gmail.com> - 2013-02-20 11:38 -0700
              Re: Python 3.3 vs. MSDOS Basic Tim Daneliuk <tundra@tundraware.com> - 2013-02-20 16:49 -0600
                Re: Python 3.3 vs. MSDOS Basic Tim Daneliuk <tundra@tundraware.com> - 2013-02-20 16:59 -0600
        Re: Python 3.3 vs. MSDOS Basic Serhiy Storchaka <storchaka@gmail.com> - 2013-02-19 22:28 +0200
        Re: Python 3.3 vs. MSDOS Basic Chris Angelico <rosuav@gmail.com> - 2013-02-20 08:39 +1100
          Re: Python 3.3 vs. MSDOS Basic Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2013-02-20 18:32 +1300
    Re: Python 3.3 vs. MSDOS Basic Chris Angelico <rosuav@gmail.com> - 2013-02-19 08:56 +1100
    Re: Python 3.3 vs. MSDOS Basic Chris Angelico <rosuav@gmail.com> - 2013-02-19 08:58 +1100
      Re: Python 3.3 vs. MSDOS Basic John Immarino <johimm@gmail.com> - 2013-02-18 17:39 -0800
        Re: Python 3.3 vs. MSDOS Basic Chris Angelico <rosuav@gmail.com> - 2013-02-19 14:01 +1100
          Re: Python 3.3 vs. MSDOS Basic Nick Mellor <thebalancepro@gmail.com> - 2013-02-18 20:17 -0800
          Re: Python 3.3 vs. MSDOS Basic Nick Mellor <thebalancepro@gmail.com> - 2013-02-18 20:17 -0800
      Re: Python 3.3 vs. MSDOS Basic John Immarino <johimm@gmail.com> - 2013-02-18 17:39 -0800
        Re: Python 3.3 vs. MSDOS Basic Neil Cerutti <neilc@norwich.edu> - 2013-02-20 17:06 +0000
    Re: Python 3.3 vs. MSDOS Basic Chris Angelico <rosuav@gmail.com> - 2013-02-19 09:01 +1100
    Re: Python 3.3 vs. MSDOS Basic Ian Kelly <ian.g.kelly@gmail.com> - 2013-02-18 15:15 -0700
    Re: Python 3.3 vs. MSDOS Basic Alexander Blinne <news@blinne.net> - 2013-02-19 01:11 +0100
    Re: Python 3.3 vs. MSDOS Basic Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2013-02-18 19:36 -0500
      Re: Python 3.3 vs. MSDOS Basic John Immarino <johimm@gmail.com> - 2013-02-18 17:47 -0800
      Re: Python 3.3 vs. MSDOS Basic John Immarino <johimm@gmail.com> - 2013-02-18 17:47 -0800
    Re: Python 3.3 vs. MSDOS Basic Terry Reedy <tjreedy@udel.edu> - 2013-02-18 19:50 -0500
      Re: Python 3.3 vs. MSDOS Basic Piet van Oostrum <piet@vanoostrum.org> - 2013-02-19 12:42 +0100
        Re: Python 3.3 vs. MSDOS Basic Alexander Blinne <news@blinne.net> - 2013-02-20 01:23 +0100
          Re: Python 3.3 vs. MSDOS Basic Ian Kelly <ian.g.kelly@gmail.com> - 2013-02-19 18:04 -0700
    Re: Python 3.3 vs. MSDOS Basic Terry Reedy <tjreedy@udel.edu> - 2013-02-19 00:28 -0500
    Re: Python 3.3 vs. MSDOS Basic Anssi Saari <as@sci.fi> - 2013-02-19 12:52 +0200
    Re: Python 3.3 vs. MSDOS Basic Serhiy Storchaka <storchaka@gmail.com> - 2013-02-19 13:13 +0200
    Re: Python 3.3 vs. MSDOS Basic Olive <diolu.remove_this_part@bigfoot.com> - 2013-02-19 15:02 +0100

Page 2 of 2 — ← Prev page 1 [2]


#39135

FromChris Angelico <rosuav@gmail.com>
Date2013-02-19 09:01 +1100
Message-ID<mailman.1977.1361224874.2939.python-list@python.org>
In reply to#39117
On Tue, Feb 19, 2013 at 8:54 AM, Ian Kelly <ian.g.kelly@gmail.com> wrote:
> Well, I don't see anything that looks especially slow in that code,
> but the algorithm that you're using is not very efficient.  I rewrote
> it using dynamic programming (details left as an exercise), which got
> the runtime down to about 4 seconds.

Did it involve a dictionary, mapping a value to its count, so that any
time you hit a value you've seen, you can short-cut it? That was my
first optimization consideration, though I didn't implement it in any
version, so as to keep the timings comparable.

ChrisA

[toc] | [prev] | [next] | [standalone]


#39136

FromIan Kelly <ian.g.kelly@gmail.com>
Date2013-02-18 15:15 -0700
Message-ID<mailman.1978.1361225801.2939.python-list@python.org>
In reply to#39117
On Mon, Feb 18, 2013 at 3:01 PM, Chris Angelico <rosuav@gmail.com> wrote:
> On Tue, Feb 19, 2013 at 8:54 AM, Ian Kelly <ian.g.kelly@gmail.com> wrote:
>> Well, I don't see anything that looks especially slow in that code,
>> but the algorithm that you're using is not very efficient.  I rewrote
>> it using dynamic programming (details left as an exercise), which got
>> the runtime down to about 4 seconds.
>
> Did it involve a dictionary, mapping a value to its count, so that any
> time you hit a value you've seen, you can short-cut it? That was my
> first optimization consideration, though I didn't implement it in any
> version, so as to keep the timings comparable.

Ayup.

[toc] | [prev] | [next] | [standalone]


#39144

FromAlexander Blinne <news@blinne.net>
Date2013-02-19 01:11 +0100
Message-ID<5122c342$0$6578$9b4e6d93@newsspool3.arcor-online.net>
In reply to#39117
Am 18.02.2013 20:13, schrieb John Immarino:
> I coded a Python solution for Problem #14 on the Project Euler website. I was very surprised to find that it took 107 sec. to run even though it's a pretty simple program.  I also coded an equivalent solution for the problem in the old MSDOS basic. (That's the 16 bit app of 1980s vintage.)  It ran in 56 sec. Is there a flaw in my coding, or is Python really this slow in this particular application. MSDOS Basic usually runs at a snails pace compared to Python.

> max=0
> m=0
> while m<=1000000:
>     m+=1
>     count=0
>     n=m
>     while n!=1:
>         count+=1
>         if n%2==0:
>             n=n//2
>         else:
>             n=3*n+1
>     if count>max:
>          max=count
>          num=m
> print(num,max)

I cannot compare my timings with basic but python 2.7.3 and python 3.2.3
are both equally slow hier (~50 sec).
pypy is a lot faster (only some old version 1.7.0, current versions
should be faster still) with about 5 sec.

The following C-Program:

#include <stdio.h>

int main(void) {

  int max = 0;
  int m = 0;
  long int n;
  int count;
  int num;

  while(m<=1000000) {
    m++;
    n = m;
    count = 0;

    while(n != 1) {
      count++;
      if(n % 2 == 0) {
        n = n / 2;
      }
      else {
        n = n*3 + 1;
      }
    }

    if(count > max) {
      max = count;
      num = m;
    }
  }

  printf("%d, %d\n", num, max);
}

Does the job in just under 1 sec.

Greetings
Alexander





[toc] | [prev] | [next] | [standalone]


#39147

FromDennis Lee Bieber <wlfraed@ix.netcom.com>
Date2013-02-18 19:36 -0500
Message-ID<mailman.1985.1361234188.2939.python-list@python.org>
In reply to#39117
On Mon, 18 Feb 2013 11:13:04 -0800 (PST), John Immarino
<johimm@gmail.com> declaimed the following in gmane.comp.python.general:

> I coded a Python solution for Problem #14 on the Project Euler website. I was very surprised to find that it took 107 sec. to run even though it's a pretty simple program.  I also coded an equivalent solution for the problem in the old MSDOS basic. (That's the 16 bit app of 1980s vintage.)  It ran in 56 sec. Is there a flaw in my coding, or is Python really this slow in this particular application. MSDOS Basic usually runs at a snails pace compared to Python.
> 
	<snip> 
> max=0

	"max" is a bad name -- it masks the built-in max() function

> m=0
> while m<=1000000:
>     m+=1

	Since "m" is only modified here and has a value of 1 for the first
pass through, you can replace those three lines with

for m in xrange(1, 1000001): #python 2.x, just use range() for 3.x

>     count=0
>     n=m

>     while n!=1:
>         count+=1
>         if n%2==0:
>             n=n//2
>         else:
>             n=3*n+1

	Avoid the comparison to 0 by reversing the then/else actions... Any
0 result is false.

-=-=-=-=-
import time

mx = 0

start = time.time()
for m in xrange(1, 1000001):
    count = 0
    n = m
    while n > 1:
        count += 1
        if n % 2:   # 0 means false
            n = 3 * n + 1
        else:
            n = n // 2

    if count > mx:
        mx, num = count, m

end = time.time()

print num, mx
print end-start
-=-=-=-=-
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

E:\UserData\Wulfraed\My Documents>cd "Python Progs"

E:\UserData\Wulfraed\My Documents\Python Progs>Script1.py
837799 524
83.2030000687

E:\UserData\Wulfraed\My Documents\Python Progs>






-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
        wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

[toc] | [prev] | [next] | [standalone]


#39162

FromJohn Immarino <johimm@gmail.com>
Date2013-02-18 17:47 -0800
Message-ID<858e93a6-205c-44b6-af90-2991ea3e9ff6@googlegroups.com>
In reply to#39147
> 
> > max=0
> 
> 
> 
> 	"max" is a bad name -- it masks the built-in max() function
> 
> 
> 
> > m=0
> 
> > while m<=1000000:
> 
> >     m+=1
> 
> 
> 
> 	Since "m" is only modified here and has a value of 1 for the first
> 
> pass through, you can replace those three lines with
> 
> 
> 
> for m in xrange(1, 1000001): #python 2.x, just use range() for 3.x
> 
> 
> 
> >     count=0
> 
> >     n=m
> 
> 
> 
> >     while n!=1:
> 
> >         count+=1
> 
> >         if n%2==0:
> 
> >             n=n//2
> 
> >         else:
> 
> >             n=3*n+1
> 
> 
> 
> 	Avoid the comparison to 0 by reversing the then/else actions... Any
> 
> 0 result is false.
> 
> 
> 
> -=-=-=-=-
> 
> import time
> 
> 
> 
> mx = 0
> 
> 
> 
> start = time.time()
> 
> for m in xrange(1, 1000001):
> 
>     count = 0
> 
>     n = m
> 
>     while n > 1:
> 
>         count += 1
> 
>         if n % 2:   # 0 means false
> 
>             n = 3 * n + 1
> 
>         else:
> 
>             n = n // 2
> 
> 
> 
>     if count > mx:
> 
>         mx, num = count, m
> 
> 
> 
> end = time.time()
> 
> 
> 
> print num, mx
> 
> print end-start
> 
> -=-=-=-=-
> 
> Microsoft Windows XP [Version 5.1.2600]
> 
> (C) Copyright 1985-2001 Microsoft Corp.
> 
> 
> 
> E:\UserData\Wulfraed\My Documents>cd "Python Progs"
> 
> 
> 
> E:\UserData\Wulfraed\My Documents\Python Progs>Script1.py
> 
> 837799 524
> 
> 83.2030000687
> 
> 
> 
> E:\UserData\Wulfraed\My Documents\Python Progs>
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> -- 
> 
> 	Wulfraed                 Dennis Lee Bieber         AF6VN
> 
>         wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

Thanks, your suggestions are well taken.

[toc] | [prev] | [next] | [standalone]


#39164

FromJohn Immarino <johimm@gmail.com>
Date2013-02-18 17:47 -0800
Message-ID<mailman.1992.1361238473.2939.python-list@python.org>
In reply to#39147
> 
> > max=0
> 
> 
> 
> 	"max" is a bad name -- it masks the built-in max() function
> 
> 
> 
> > m=0
> 
> > while m<=1000000:
> 
> >     m+=1
> 
> 
> 
> 	Since "m" is only modified here and has a value of 1 for the first
> 
> pass through, you can replace those three lines with
> 
> 
> 
> for m in xrange(1, 1000001): #python 2.x, just use range() for 3.x
> 
> 
> 
> >     count=0
> 
> >     n=m
> 
> 
> 
> >     while n!=1:
> 
> >         count+=1
> 
> >         if n%2==0:
> 
> >             n=n//2
> 
> >         else:
> 
> >             n=3*n+1
> 
> 
> 
> 	Avoid the comparison to 0 by reversing the then/else actions... Any
> 
> 0 result is false.
> 
> 
> 
> -=-=-=-=-
> 
> import time
> 
> 
> 
> mx = 0
> 
> 
> 
> start = time.time()
> 
> for m in xrange(1, 1000001):
> 
>     count = 0
> 
>     n = m
> 
>     while n > 1:
> 
>         count += 1
> 
>         if n % 2:   # 0 means false
> 
>             n = 3 * n + 1
> 
>         else:
> 
>             n = n // 2
> 
> 
> 
>     if count > mx:
> 
>         mx, num = count, m
> 
> 
> 
> end = time.time()
> 
> 
> 
> print num, mx
> 
> print end-start
> 
> -=-=-=-=-
> 
> Microsoft Windows XP [Version 5.1.2600]
> 
> (C) Copyright 1985-2001 Microsoft Corp.
> 
> 
> 
> E:\UserData\Wulfraed\My Documents>cd "Python Progs"
> 
> 
> 
> E:\UserData\Wulfraed\My Documents\Python Progs>Script1.py
> 
> 837799 524
> 
> 83.2030000687
> 
> 
> 
> E:\UserData\Wulfraed\My Documents\Python Progs>
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> -- 
> 
> 	Wulfraed                 Dennis Lee Bieber         AF6VN
> 
>         wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

Thanks, your suggestions are well taken.

[toc] | [prev] | [next] | [standalone]


#39148

FromTerry Reedy <tjreedy@udel.edu>
Date2013-02-18 19:50 -0500
Message-ID<mailman.1986.1361235083.2939.python-list@python.org>
In reply to#39117
On 2/18/2013 2:13 PM, John Immarino wrote:
> I coded a Python solution for Problem #14 on the Project Euler
> website. I was very surprised to find that it took 107 sec. to run
> even though it's a pretty simple program.  I also coded an equivalent
> solution for the problem in the old MSDOS basic. (That's the 16 bit
> app of 1980s vintage.)  It ran in 56 sec. Is there a flaw in my
> coding, or is Python really this slow in this particular application.
> MSDOS Basic usually runs at a snails pace compared to Python.

I find this surprising too. I am also surprised that it even works, 
given that the highest intermediate value is about 57 billion and I do 
not remember that Basic had infinite precision ints.

> The following iterative sequence is defined for the set of positive
> integers:
>
> n → n/2 (n is even) n → 3n + 1 (n is odd)

Note that if n is odd, 3n + 1 is even (and not 1!), so one may take two 
steps with (3n + 1)/2.

> Using the rule above and starting with 13, we generate the following
> sequence: 13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1
>
> It can be seen that this sequence (starting at 13 and finishing at 1)
> contains 10 terms. Although it has not been proved yet (Collatz
> Problem), it is thought that all starting numbers finish at 1.

https://en.wikipedia.org/wiki/Collatz_conjecture

> Which starting number, under one million, produces the longest
> chain?

I suppose 'print(837799)' would not count as a proper solution.

> NOTE: Once the chain starts the terms are allowed to go above one
> million.

Here is my slightly revised code with timings on a good, 20 month old 
win 7 machine.

from time import time
start = time()

num, max = 0, 0
for m in range(1, 1000001):
     n = m
     count=0
     while n !=1:
         if n & 1:  #n % 2:
             n = (3*n + 1) // 2
             count += 2
         else:
             n = n//2
             count += 1
     if count > max:
          num = m
          max = count

print(num, max , time()-start)

# original: 837799, 524 steps, 53.9 secs
# for ... range: 52.3
# reverse inner if 49.0
# double step 39.1
# n & 1 instead of n % 2 for test: 36.0, 36.0,  35.9
# n>>1  instead of n//2: 34.7, 36.1, 36.2;
# this may be internally optimized, so skip

I do not see any fluff left to remove, unless one takes the major step 
of saving already calculated values in an array.

Since the highest intermediate value of n is 56991483520 (445245965
*2**7, from adding "if n > maxn: maxn = n" to the odd branch, before 
dividing by 2), the array would have to be limited to a much lower 
value, say a few million.

-- 
Terry Jan Reedy

[toc] | [prev] | [next] | [standalone]


#39208

FromPiet van Oostrum <piet@vanoostrum.org>
Date2013-02-19 12:42 +0100
Message-ID<m2liaka5t4.fsf@cochabamba.vanoostrum.org>
In reply to#39148
Terry Reedy <tjreedy@udel.edu> writes:

> On 2/18/2013 2:13 PM, John Immarino wrote:
>> I coded a Python solution for Problem #14 on the Project Euler
>> website. I was very surprised to find that it took 107 sec. to run
>> even though it's a pretty simple program.  I also coded an equivalent
>> solution for the problem in the old MSDOS basic. (That's the 16 bit
>> app of 1980s vintage.)  It ran in 56 sec. Is there a flaw in my
>> coding, or is Python really this slow in this particular application.
>> MSDOS Basic usually runs at a snails pace compared to Python.
>
> I find this surprising too. I am also surprised that it even works,
> given that the highest intermediate value is about 57 billion and I do
> not remember that Basic had infinite precision ints.

That may explain why the Basic version is faster: it gets overflow and
then it may have taken some shortcuts.
-- 
Piet van Oostrum <piet@vanoostrum.org>
WWW: http://pietvanoostrum.com/
PGP key: [8DAE142BE17999C4]

[toc] | [prev] | [next] | [standalone]


#39294

FromAlexander Blinne <news@blinne.net>
Date2013-02-20 01:23 +0100
Message-ID<51241780$0$9523$9b4e6d93@newsspool1.arcor-online.net>
In reply to#39208
Am 19.02.2013 12:42, schrieb Piet van Oostrum:
> Terry Reedy <tjreedy@udel.edu> writes:
>> I find this surprising too. I am also surprised that it even works,
>> given that the highest intermediate value is about 57 billion and I do
>> not remember that Basic had infinite precision ints.
> 
> That may explain why the Basic version is faster: it gets overflow and
> then it may have taken some shortcuts.

Consider this C program

#include <stdio.h>

int main(void) {

  int max = 0;
  int m = 0;
  long int n;
  int count;
  int num;

  while(m<=1000000) {
    m++;
    n = m;
    count = 0;

    while(n != 1) {
      count++;
      if(n % 2 == 0) {
        n = n / 2;
      }
      else {
        n = n*3 + 1;
      }
    }

    if(count > max) {
      max = count;
      num = m;
    }
  }

  printf("%d, %d\n", num, max);
}

If the line

long int n;

is changed into

unsigned int n;

the program runs in 0.68 sec instead of 0.79, so there is some shortcut.
If changed into

signed int n;

there is a veeery long, perhaps infinite loop.

Greetings
Alexander

[toc] | [prev] | [next] | [standalone]


#39296

FromIan Kelly <ian.g.kelly@gmail.com>
Date2013-02-19 18:04 -0700
Message-ID<mailman.2075.1361322337.2939.python-list@python.org>
In reply to#39294
On Tue, Feb 19, 2013 at 5:23 PM, Alexander Blinne <news@blinne.net> wrote:
> If changed into
>
> signed int n;
>
> there is a veeery long, perhaps infinite loop.

Yes, infinite.  Here's the first such sequence encountered with a
signed 32-bit int.

[113383, 340150, 170075, 510226, 255113, 765340, 382670, 191335,
574006, 287003, 861010, 430505, 1291516, 645758, 322879, 968638,
484319, 1452958, 726479, 2179438, 1089719, 3269158, 1634579, 4903738,
2451869, 7355608, 3677804, 1838902, 919451, 2758354, 1379177, 4137532,
2068766, 1034383, 3103150, 1551575, 4654726, 2327363, 6982090,
3491045, 10473136, 5236568, 2618284, 1309142, 654571, 1963714, 981857,
2945572, 1472786, 736393, 2209180, 1104590, 552295, 1656886, 828443,
2485330, 1242665, 3727996, 1863998, 931999, 2795998, 1397999, 4193998,
2096999, 6290998, 3145499, 9436498, 4718249, 14154748, 7077374,
3538687, 10616062, 5308031, 15924094, 7962047, 23886142, 11943071,
35829214, 17914607, 53743822, 26871911, 80615734, 40307867, 120923602,
60461801, 181385404, 90692702, 45346351, 136039054, 68019527,
204058582, 102029291, 306087874, 153043937, 459131812, 229565906,
114782953, 344348860, 172174430, 86087215, 258261646, 129130823,
387392470, 193696235, 581088706, 290544353, 871633060, 435816530,
217908265, 653724796, 326862398, 163431199, 490293598, 245146799,
735440398, 367720199, 1103160598, 551580299, 1654740898, 827370449,
-1812855948, -906427974, -453213987, -1359641960, -679820980,
-339910490, -169955245, -509865734, -254932867, -764798600,
-382399300, -191199650, -95599825, -286799474, -143399737, -430199210,
-215099605, -645298814, -322649407, -967948220, -483974110,
-241987055, -725961164, -362980582, -181490291, -544470872,
-272235436, -136117718, -68058859, -204176576, -102088288, -51044144,
-25522072, -12761036, -6380518, -3190259, -9570776, -4785388,
-2392694, -1196347, -3589040, -1794520, -897260, -448630, -224315,
-672944, -336472, -168236, -84118, -42059, -126176, -63088, -31544,
-15772, -7886, -3943, -11828, -5914, -2957, -8870, -4435, -13304,
-6652, -3326, -1663, -4988, -2494, -1247, -3740, -1870, -935, -2804,
-1402, -701, -2102, -1051, -3152, -1576, -788, -394, -197, -590, -295,
-884, -442, -221, -662, -331, -992, -496, -248, -124, -62, -31, -92,
-46, -23, -68, -34, -17, -50, -25, -74, -37, -110, -55, -164, -82,
-41, -122, -61, -182, -91, -272, -136, -68, ...]

[toc] | [prev] | [next] | [standalone]


#39184

FromTerry Reedy <tjreedy@udel.edu>
Date2013-02-19 00:28 -0500
Message-ID<mailman.2006.1361251752.2939.python-list@python.org>
In reply to#39117
On 2/18/2013 4:55 PM, Chris Angelico wrote:

> Running under Python 2.6, both your version and mine take about 90
> seconds to run. But under Python 3.3, where (among other things)
> range() yields values lazily, my version is significantly faster than
> yours. BUT! Both versions, under 3.3, are significantly *slower* than
> under 2.6. My first thought is that it's because Py2 has different
> types for 'int' and 'long', and Py3 doesn't (effectively, everything's
> a long), so I added an L suffix to every number and ran each of them
> under 2.6 again. Seems that was the bulk of the difference, though not
> all.
>
> Pythonistas, does this count as a regression, or is Python
> sufficiently "not a number crunching language" that we don't care?

Both. This brute-force algorithm is almost pure number crunching. This 
is the sort of thing pypy and cython are good at speeding up. (I leave 
out numpy only because it is not an array-oriented problem.)

I put a counter in the inner loop of my improved version the does 
(3*n+1)//2 in one step and got 87 826 478 in 40 seconds (without the 
counter). That is 2 million loops per second and each loop does a 
compare, one or two integer ops, and creates and releases one or two ints.

If I were doing a lot of int crunching like this with CPython and were 
building my own interpreter, I would greatly expand the range of 
pre-allocated 'small' ints to avoid some of the repeated allocation and 
de-allocation. On a multi-gibibyte machine, allocating up to 1000000 
instead of 256 would be feasible.

As Ian noted, an intelligent algorithm in CPython can match pypy and is 
in the ballpark of C, but is much easier to write in Python than C. It 
is possible that Ian's code could be improved further. A pre-allocated 
arrray + dict might be faster. Whenever an odd value is filled in, 
powers of 2 times that value can also be.

-- 
Terry Jan Reedy

[toc] | [prev] | [next] | [standalone]


#39205

FromAnssi Saari <as@sci.fi>
Date2013-02-19 12:52 +0200
Message-ID<vg3r4kcshhq.fsf@coffee.modeemi.fi>
In reply to#39117
John Immarino <johimm@gmail.com> writes:

> I coded a Python solution for Problem #14 on the Project Euler
> website. I was very surprised to find that it took 107 sec. to run
> even though it's a pretty simple program.  I also coded an equivalent
> solution for the problem in the old MSDOS basic. (That's the 16 bit
> app of 1980s vintage.)

Just out of curiosity, can you post the basic version as well?

[toc] | [prev] | [next] | [standalone]


#39206

FromSerhiy Storchaka <storchaka@gmail.com>
Date2013-02-19 13:13 +0200
Message-ID<mailman.2015.1361272428.2939.python-list@python.org>
In reply to#39117
On 18.02.13 21:13, John Immarino wrote:
> max=0
> m=0
> while m<=1000000:
>      m+=1
>      count=0
>      n=m
>      while n!=1:
>          count+=1
>          if n%2==0:
>              n=n//2
>          else:
>              n=3*n+1
>      if count>max:
>           max=count
>           num=m
> print(num,max)

Some minor tips:

1. Use range() for m iteration.
2. Instead of "if n%2==0:" use just "if n%2:".
3. Convert all you code to a function. Python is a little faster with 
locals than with globals.

In sum all this tips will speedup your code about 2x.

And one big tip:

Use cashing (and recursion). This will speedup your code more than 10x.

[toc] | [prev] | [next] | [standalone]


#39224

FromOlive <diolu.remove_this_part@bigfoot.com>
Date2013-02-19 15:02 +0100
Message-ID<20130219150240.42707966@pcolivier.chezmoi.net>
In reply to#39117
> max=0
> m=0
> while m<=1000000:
>     m+=1
>     count=0
>     n=m
>     while n!=1:
>         count+=1
>         if n%2==0:
>             n=n//2
>         else:
>             n=3*n+1
>     if count>max:
>          max=count
>          num=m
> print(num,max)
> 

I have tried to run your program with pypy (Python git compiler) (http://pypy.org/), it runs about 15x faster (8 sec instead of 2m2sec in my old Celeron M420 computer).

Olive

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

Back to top | Article view | comp.lang.python


csiph-web