Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-4041-

FIOC is SAF (Slow as Fuck)

Name: Anonymous 2008-10-13 20:16

While reading my SICP, I found a neat fibonacci function that has log n operations. I looks something like this.


(define (fib n)
  (fib-iter 1 0 0 1 n))

(define (fib-iter a b p q count)
  (cond ((= count 0) b)
        ((even? count)
         (fib-iter a
                   b
                   (+ (* p p) (* q q))     ; compute p'
                   (+ (* q q) (* 2 p q))   ; compute q'
                   (/ count 2)))
        (else (fib-iter (+ (* b q) (* a q) (* a p))
                        (+ (* b p) (* a q))
                        p
                        q
                        (- count 1)))))


So I implemented it in Haskell, just for fun.


fib n = fib' 1 0 0 1 n
  where fib' a b p q 0 = b
        fib' a b p q n | even n =
          fib' a b (p * p + q * q) (q * q + 2 * p * q) (n `div` 2)
        fib' a b p q n =
          fib' (b * q + a * q + a * p) (b * p + a * q) p q (n - 1)


To calculate and print fib(1000000) and fib(10000000) (i.e. the millionth and ten-millionth fibonacci numbers) takes about 3.26 seconds with the Haskell version (when compiled with GHC), and 43.24 seconds with the Scheme version (when interpreted by plt-r5rs, cause I can't figure out how to get it to be r6rs compliant, nor can I figure out how to make the compiler accept r5rs code :( )

Just to have some more fun, I also implemented it iteratively in Python.


def fib(n):
    a = 1
    b = 0
    p = 0
    q = 1

    while n > 0:
        if n % 2 == 0:
            new_p = p * p + q * q
            new_q = q * q + 2 * p * q
            n = n / 2
            p = new_p
            q = new_q
        else:
            new_a = b * q + a * q + a * p
            new_b = b * p + a * q
            n = n - 1
            a = new_a
            b = new_b

    return b


This takes CPython a whopping 1926.49 seconds to calculate the same numbers. Holy fuck, /prog/, maybe you're right about FIOC after all.

Here are the other implementations I've written and their times.

Ruby (995.35 seconds)

def fib(n)
    a = 1
    b = 0
    p = 0
    q = 1

    while n > 0
        if n % 2 == 0:
            new_p = p * p + q * q
            new_q = q * q + 2 * p * q
            n = n / 2
            p = new_p
            q = new_q
        else
            new_a = b * q + a * q + a * p
            new_b = b * p + a * q
            n = n - 1
            a = new_a
            b = new_b
        end
    end
    b
end


C using GMP (3.24 seconds)

void fib(unsigned long n)
{
    mpz_t a, b, p, q, tmp1, tmp2, tmp3;

    mpz_init(a);
    mpz_init(b);
    mpz_init(p);
    mpz_init(q);
    mpz_init(tmp1);
    mpz_init(tmp2);
    mpz_init(tmp3);

    mpz_set_ui(a, 1);
    mpz_set_ui(b, 0);
    mpz_set_ui(p, 0);
    mpz_set_ui(q, 1);

    while(n > 0)
    {
        if(n % 2 == 0)
        {
            // p * p + q * q
            mpz_mul(tmp1, p, p);
            mpz_mul(tmp2, q, q);
            mpz_add(tmp3, tmp1, tmp2);

            // q * q + 2 * p * q;
            mpz_mul_ui(tmp1, p, 2);
            mpz_add(tmp1, tmp1, q);
            mpz_mul(tmp1, tmp1, q);

            mpz_set(p, tmp3);
            mpz_set(q, tmp1);
            n >>= 1;
        }
        else
        {
            // b * q + a * q + a * p;
            mpz_mul(tmp1, b, q);
            mpz_mul(tmp2, a, q);
            mpz_mul(tmp3, a, p);
            mpz_add(tmp3, tmp3, tmp2);
            mpz_add(tmp3, tmp3, tmp1);

            // b * p + a * q;
            mpz_mul(tmp1, b, p);
            mpz_mul(b, a, q);
            mpz_add(b, tmp1, b);

            mpz_set(a, tmp3);
            n--;
        }
    }

    gmp_printf("%Zd\n", b);

    mpz_clear(a);
    mpz_clear(b);
    mpz_clear(p);
    mpz_clear(q);
    mpz_clear(tmp1);
    mpz_clear(tmp2);
    mpz_clear(tmp3);
}

Name: Anonymous 2008-10-13 20:55

Those GHC writers are truly epic.

Name: Anonymous 2008-10-13 21:00

Fibonacci can be done in O(1)
:O

Name: Anonymous 2008-10-13 21:36

I don't want to call you out as a troll, but perhaps your benchmarks are slightly off?

root@suigintou> nice -n -5 time python fib.py
       60.43 real        60.20 user         0.01 sys
root@suigintou> nice -n -5 time ruby fib.rb
      176.65 real       175.92 user         0.03 sys
root@suigintou> python --version
Python 2.5.2
root@suigintou> ruby --version
ruby 1.8.6 (2008-08-11 patchlevel 287) [amd64-freebsd7]

Name: Anonymous 2008-10-13 21:40

Haskell has been gaining some support in here, at least from me, Taro, and you (I assume you are the Sussman?). I used to be a LISPfag but recently I've been quite enjoying the performance and beautiful tools that Haskell offers. I orgasmed the first time I wrote code with list comprehension.

The LISP performance still isn't bad at all if it's really interpreted. I'd be curious to see a compiled version (Stalin/etc), although I won't be assed to do it.

Name: Anonymous 2008-10-13 21:53

>>4
I didn't adjust nice levels at all. I'll try that later and see what happens.

Are you sure you're calculating the millionth (1000000) and ten-millionth (10000000) fibonacci numbers?

Name: Anonymous 2008-10-13 22:03

>>3
no, it can't. it can be calculated in O(log n) at best.

Name: Anonymous 2008-10-13 22:04

>>6
For both of them, I'm calculating the ten-millionth fibonacci numbers --

fib( 10000000 )

Realistically, I think the benchmark is more a test of the bigint implementation of the language (but then again, there really isn't such thing as a generalized benchmark anyway). I tested on an amd64 machine -- what platform are you on? It might be a platform-specific implementation issue with CPython or something.

The excessively long Ruby time is pretty strange too, but I'm not at all familiar with Ruby's internals.

Name: Anonymous 2008-10-13 22:11

>>7
I don't understand

Name: Anonymous 2008-10-13 22:25

>>7
Memoization

Name: Anonymous 2008-10-13 22:28

Here's my Python script verbatim.


def fib(n):
    a = 1
    b = 0
    p = 0
    q = 1

    while n > 0:
        if n % 2 == 0:
            new_p = p * p + q * q
            new_q = q * q + 2 * p * q
            n = n / 2
            p = new_p
            q = new_q
        else:
            new_a = b * q + a * q + a * p
            new_b = b * p + a * q
            n = n - 1
            a = new_a
            b = new_b

    return b

print fib(1000000)
print fib(10000000)

Name: Anonymous 2008-10-13 22:50

>>11
Ah, your problem there is that Python's (and Ruby's, for that matter) str(bigint) conversion is slow as fuck and is causing the bottleneck. Your fibonacci algorithm may be O(log(N)), but binary to decimal conversion is a O(n2)1 operation which takes up the majority of the computation time.

That said, the other languages do the same conversion much faster. I suspect it's a performance bug of some sort (or just an accepted limitation) in the Python and Ruby libraries.

                                 
References: [1] http://mail.python.org/pipermail/python-list/2004-July/270235.html

Name: Anonymous 2008-10-13 22:50

FIOC
Thread is over, you may go to sleep now everyone.

Name: Anonymous 2008-10-13 23:07

>>9,10
exponentiation requires at least O(log n). even with memoization it's still O(log n) the first time for each number.

Name: Anonymous 2008-10-13 23:24

>>12
Ha, you're right. Maybe CPython should change it's bigint to use GMP, since that seems to be fast.

Name: Anonymous 2008-10-14 0:14

>>15
or maybe people should let cpython die and use one of the better implementations of python

Name: Anonymous 2008-10-14 0:20

>>16
We'll all switch to PyPy when it becomes reasonable, but until it outperforms CPython we'll stick with CPython. Let's not even talk about any of the other implementations. They're all either incomplete, utter shit, or both.

Name: Anonymous 2008-10-14 2:09

Name: Anonymous 2008-10-14 6:08

>>18
Sorry, I like using stacks in my programs.  And I cannot see how that would work anyway -- how would you call library functions without the stack?

Name: Anonymous 2008-10-14 6:13

>>19
"Stackless Python, or Stackless, is a Python programming language interpreter, so named because it avoids depending on the C call stack for its own stack."

Name: Anonymous 2008-10-14 6:24

no, it can't. it can be calculated in O(log n) at best.
F(n) = φn−(1−φ)n
          √5

Name: Anonymous 2008-10-14 6:25

>>20
It's shit.

Name: Anonymous 2008-10-14 6:29

>>21
see >>14

Name: Anonymous 2008-10-14 6:31

>>23
See >>21 for Ο(1).

Name: Anonymous 2008-10-14 6:31

>>22
It's better than CPython.

Name: Anonymous 2008-10-14 6:34

>>25
Stackless is basically CPython, and IronPython is indeed shit (as in slower than CPython). I can find references for the later fact if you really want to troll me good.

Name: Anonymous 2008-10-14 6:40

>>22
CURRY BUTT xDDDDD~~~

Name: Anonymous 2008-10-14 7:01

>>24
[b]n[b]
http://en.wikipedia.org/wiki/Exponentiation#Efficiently_computing_a_power
In general, the number of multiplication operations required to compute an can be reduced to Θ(log n) by using exponentiation by squaring or (more generally) addition-chain exponentiation.

Name: Anonymous 2008-10-14 7:18

>>28
BBCODE FAILURE renders your argument invalid.

Name: Anonymous 2008-10-14 7:24

>>29
MATHS FAILURE renders your argument invalid.

Name: Anonymous 2008-10-14 8:14

>>28
pow is O(1), your point is moot.

Name: Anonymous 2008-10-14 9:14

>>31
pow is O(log n), your point is moot.

Name: Anonymous 2008-10-14 10:34

>>32
pow is O(log log n), your point is snacks.

Name: Anonymous 2008-10-14 10:40

Too bad Ruby Python is slow as fuck.

Name: Anonymous 2008-10-14 10:42

>>33
your point is squeeks and pow is O(log log log n).

Name: Anonymous 2008-10-14 10:46

>>35
Your point is reeses and I had it for breakfast.

Name: Anonymous 2008-10-14 11:33

>>36
pow is O(log log log log n) and you're back to /b/, please

Name: Anonymous 2008-10-14 15:58

pow is O(logk n) where k=0,1,2,...

Name: Anonymous 2008-10-14 16:01

What the devil does FIOC mean anyway.

The wonderful thing about the Haskell version is that it looks human-readable, unlike the C version, yet runs at about the same speed. Score! ... not that I dislike C, far from it.

Name: Anonymous 2008-10-14 16:25

>>21
just an approximation.

Name: Anonymous 2008-10-14 17:20

>>39
In case this isn't a troll, it means the
Forced Indentation Of Code

Name: Anonymous 2008-10-15 4:31

>>41
[spoiler][b][i]FORCED INDENTATION OF THE CODE[/spoiler]

Name: Anonymous 2008-10-15 4:32

>>43
[u][o][b][i]BBCODE[sub]FAILURE[/i][/b][/o][/u]

Name: Anonymous 2008-10-15 4:34

C-C-C-Combo breaker

Back to /b/

Name: Anonymous 2008-10-15 8:58

>>41
Oh right. Should've remembered that. I guess Haskell doesn't qualify as it has the curlies-and-semicolons mode too.

Name: Anonymous 2008-10-16 0:30

>>40
it's only an approximation when you're approximating the irrational numbers.

Name: Anonymous 2008-10-16 5:09

>>45
Haskell: OIOC

Name: Anonymous 2008-10-16 5:43

FIOC is SAF (Suave as Fuck)

Name: Anonymous 2008-10-17 4:08

>>48
You're quite mistaken
                       //`'''```,
             o        // LISP   `.,
       ,....OOo.   .c;.',,,.'``.,,.`
    .'      ____.,'.//
   / _____  \___/.'
  | / ||  \\---\|
  ||  ||   \\  ||
  co  co    co co

Are you SUAVE?
Are you a SPACE TOAD?
Are you a SUAVE SPACE TOAD?

If you answered "Yes" to all of the above questions, then SICP (STRUCTURE AND INTERPRETATION OF COMPUTER PROGRAMS) might be exactly what you've been looking for! Read SICP (STRUCTURE AND INTERPRETATION OF COMPUTER PROGRAMS) today, and enjoy all the benefits of being a satorized SICP reader. SICP (STRUCTURE AND INTERPRETATION OF COMPUTER PROGRAMS) is the fastest-growing SMUG LISP WEENIE community with THOUSANDS of members all over the Internet! You, too, can be a part of SICP if you join today! Why not? It's quick and easy - only 3 simple steps!
• First, you have to obtain a copy of SICP and read it. You can read it online using your favorite web browser.
• Second, you need to succeed in founding a Lisp-related meme in /prog/ on world4chan, a popular "programming for trolls" website.
• Third, you need to join the official SICP home /prog/ on world4chan, and apply for membership.
Talk to one of the satorized overlords or any of the other members in the board to sign up today! Upon submitting your application, you will be required to submit links to your successful meme, and you will be tested on your knowledge of STRUCTURE AND INTERPRETATION OF COMPUTER PROGRAMS. If you are having trouble locating /prog/, the official STRUCTURE AND INTERPRETATION OF COMPUTER PROGRAMS board, you might be on a wrong web sight. The correct address is >>>/prog/. Follow this link if you are using a http client such as telnet. If you have Sussman points and would like to support SICP, please don't sage this post.

Name: Anonymous 2008-10-17 4:53

>>49
Precious kopipe.

Name: Anonymous 2008-10-17 7:37

>>50
I'd know, I wrote it!

Name: Anonymous 2008-10-17 8:58

>>51
This may have surprised me.

Name: Anonymous 2008-10-17 9:20

It's quite possibly one of the saddest forms of abuse. Not physical, not emotional, but chemical. Yes, I'm talking about people whose mothers abused them with drugs and alcohol when they were small or even unborn children.
 
Did your mother switch from cheap beer to hard liquor when she found out she was pregnant with you? When you were deeply disturbed by the ending of Return of the Jedi when you were 3 years old, did she let you hit her joint and think it was funny when you choked on the weed smoke? Did your mother, when you were 4 years old, let you snort some lines off her "magic mirror" after you caught her doing the same, and get mad when you became hyper for some reason shortly thereafter?
 
If so, you should visit dis.4chan.org/prog/. Here you can share your stories of your strung-out mother and her attempts to poison you with her narcotics. It's not funny, and it's not cute. It's abuse. And it hurts.

Name: Anonymous 2008-10-17 9:59

>>1
lol @ GMP
./fib_gmp 10000001  26.74s user 0.38s system 94% cpu 28.763 total
./fib_arprec 10000001  14.49s user 10.11s system 93% cpu 26.373 total

Name: Anonymous 2009-01-22 10:32

>>38
pow is O(limk→∞logkn)

Name: Anonymous 2009-01-22 10:46

>>47
Python: FIOC
Sepples: OIOC
Haskell: OFIOC

Name: Anonymous 2009-01-22 11:07

>>11
def fib(n):
    a, b, p, q = 1, 0, 0, 1
    while n > 0:
        while not(n & 1):
            p, q = p * p + q * q, q * q + 2 * p * q
            n >>= 1
        n -= 1
        a, b = b * q + a * q + a * p, b * p + a * q
    return b

Not actually any faster in python, but if you were doing a lower-level version it would probably shave some time off.

Name: Anonymous 2010-12-06 10:02

Back to /b/, ``GNAA Faggot''

Name: Anonymous 2010-12-10 11:55

Name: Anonymous 2011-10-08 5:16

|uoɥʇʎd| ( ° o °)

|Lua| ( ^ ~ ^)



function _fib(n)
    local a = 1
    local b = 0
    local p = 0
    local q = 1
    while n > 0 do
        if n % 2 == 0 then
            new_p = p * p + q * q
            new_q = q * q + 2 * p * q
            n = n / 2
            p = new_p
            q = new_q
        else
            new_a = b * q + a * q + a * p
            new_b = b * p + a * q
            n = n - 1
            a = new_a
            b = new_b
        end
    end
    return b
end


function fib(value)
    print(string.format("fib(%d) = %d", value, _fib(value)))
end

print(fib(1000000))
print(fib(10000000))


and if it weren't for that darn bigint bug in luajit, i'm sure this example would be by far the fastest

Name: Anonymous 2011-10-09 2:03

>>40

Yeah it depends on the approximation you are using for the golden ratio. Since you know the result should be an integer, you are good if you can keep the error strictly less than (1/2). But in order to do that for calculations of large fibonachi numbers, you'll need better and better approximations for the golden ratio.

Name: Anonymous 2011-10-09 5:28

>>62
You forgot local variable scope for new_p and new_q, ``faggot''.  Put that up your shitpipe and smoke it.

Name: Anonymous 2011-10-09 8:49

>>64
True, but that isn't going to change the result, only the scope of the variables...

Name: Anonymous 2011-10-09 9:36

list if perfect language on factorials calculation

Name: Anonymous 2011-10-09 9:36

*lisp

Name: Anonymous 2011-10-09 12:30

This would be a better benchmark without the printing. Here are my results:

C (gcc 4.6.1, -O2): 0.674 s
Haskell (ghc 7.0.2, -O3): 0.514 s
Common Lisp (sbcl 1.0.43): 65.428 s

For C and Haskell, I tested all optimization levels and used the fastest. I don't know anything about optimizing CL so I'm sure it could be a lot faster.

Name: Anonymous 2011-10-09 12:32

>>66
ive got a tewwible lithp but lithps in lithp are better than lithps in lua or pyfon

Hmhm.

Name: Anonymous 2011-10-09 12:43

You don't time output to screen, that's retarded, you're retarded. Fuck you, faggot.

Name: Anonymous 2011-10-09 17:58

>>56
I understand FIOC, but what are the other two?

Sepples: OIOC
Haskell: OFIOC

Name: Anonymous 2011-10-09 18:08

>>71
Optional (Forced) Indentation Of Code

Don't change these.
Name: Email:
Entire Thread Thread List