Deutsch   English   Français   Italiano  
<87y1523hwz.fsf@gmail.com>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: ...!Xl.tags.giganews.com!local-4.nntp.ord.giganews.com!news.giganews.com.POSTED!not-for-mail
NNTP-Posting-Date: Sun, 11 Aug 2024 20:48:27 +0000
From: steve g <sgonedes1977@gmail.com>
Newsgroups: comp.lang.lisp
Subject: Re: Optimization flag for unchecked fixnums in SBCL?
References: <87h6bwrufd.fsf@nightsong.com>
Date: Sun, 11 Aug 2024 16:48:12 -0400
Message-ID: <87y1523hwz.fsf@gmail.com>
User-Agent: Gnus/5.13 (Gnus v5.13)
Cancel-Lock: sha1:NCyAJ1MkKix3iupM7Ms/Q1yGyhU=
MIME-Version: 1.0
Content-Type: text/plain
Lines: 94
X-Usenet-Provider: http://www.giganews.com
X-Trace: sv3-0wiVSwBEQ0yL26jt3qsUdRdaoSivdKQOZRvDK9jWoo0FIQtpNnfLjkgZQavwBGYWi8mgGvD9bZkdY3e!1djox+d0lh7+SEmbKkiPU8zaIoNeONGD7VcLAC5RAyE61KY=
X-Complaints-To: abuse@giganews.com
X-DMCA-Notifications: http://www.giganews.com/info/dmca.html
X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers
X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly
X-Postfilter: 1.3.40
Bytes: 3931

Paul Rubin <no.email@nospam.invalid> writes:

> I looked in the manual and didn't see a way to do this.  The following
> Haskell code (Euler problem 14) takes about 0.5 seconds on my old laptop:
>
>     cl :: Int -> Int
>     cl n = if odd n then 3*n+1 else n`quot`2
>     dl n = (1+) . length . takeWhile (/= 1) . iterate cl $ n
>     main = print . maximum $ [(dl n, n) | n <- [1..1000000]]
>
> Int is Haskell's built-in fixnum type.  Integer is bignums and that
> version takes about 7 seconds.
>
> The below CL version takes 5 seconds (this is chopped down from a
> memoized version that takes about 0.2 seconds).  I tried a few different
> ways to tell the compiler that `collatz' should take and return fixnums,
> but I didn't find the right way.  Any help?  Thanks.
>
>     (defun collatz (n)
>       (cond ((oddp n) (1+ (* 3 n)))
>             (t (floor n 2))))
>
>     (defun clen (n)
>       (cond ((= n 1) 1)
>             ((<= n 0) 'crash)
>             (t (1+ (clen (collatz n))))))
>
>     (defun run (&optional (n 1) (mi 0) (ma 0))
>         (if (> n 1000000)
>           (list mi ma)
>           (let ((a (clen n))
>                 (nn (1+ n)))
>             (if (> a ma)
>                 (run nn n a)
>                 (run nn mi ma)))))
>     (print (run))
>     (terpri)


I don't understand the math but here is a quick change that shaves it
down some.

CL-USER> (time (run))
Evaluation took:
  2.054 seconds of real time
  2.052833 seconds of total run time (2.052229 user, 0.000604 system)
  99.95% CPU
  4,733,868,882 processor cycles
  0 bytes consed
  
(837799 525)

WARNING: redefining COMMON-LISP-USER::COLLATZ in DEFUN
COLLATZ
CL-USER> (compile 'collatz)
COLLATZ
NIL
NIL
CL-USER> (time (run))
Evaluation took:
  1.626 seconds of real time
  1.625390 seconds of total run time (1.625332 user, 0.000058 system)
  99.94% CPU
  3,748,148,144 processor cycles
  0 bytes consed
  
(837799 525)
CL-USER>


Here is an assist. you are getting killed with clen. i don't understand
the math well; but this should help.

(defun collatz (n)
  ;; declare the type N to number
  (declare (type number n)
           (optimize (speed 3) (space 0) (safety 0)))
  ;; this ensures N is < 32-bits wide and zeros out the rest of the bits.
  (setq n (mask-field (byte 32 0) n))
  ;; the compiler can assume N has enough space for simple arithmetic as
  ;; opposed to generic functions.
  (cond ((oddp n)
         (1+ (* 3 n)))
        (t
         ;; this will ensure that only one value is returned from floor.
         ;; Normally floor returns 2 values - here we tell the compiler that
         ;; we only want the first value.
         (nth-value 0 (floor n 2)))))


your problem with clen is the generic+ at the end of your cond
statement. I'm going to try this in C. What haskell compiler do you use?

anyway this should help (i think).