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


Groups > comp.lang.forth > #4626 > unrolled thread

Forth Performance Question

Started byTS <thinksquared@gmail.com>
First post2011-08-06 20:43 -0700
Last post2011-08-12 20:53 +0200
Articles 20 on this page of 53 — 21 participants

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


Contents

  Forth Performance Question TS <thinksquared@gmail.com> - 2011-08-06 20:43 -0700
    Re: Forth Performance Question "Rod Pemberton" <do_not_have@noavailemail.cmm> - 2011-08-07 01:02 -0400
      Re: Forth Performance Question Chris Hinsley <chris.hinsley@gmail.com> - 2011-08-16 12:09 +0100
        Re: Forth Performance Question stephenXXX@mpeforth.com (Stephen Pelc) - 2011-08-16 14:08 +0000
    Re: Forth Performance Question mhx@iae.nl (Marcel Hendrix) - 2011-08-07 07:45 +0200
      Re: Forth Performance Question anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2011-08-07 16:18 +0000
    Re: Forth Performance Question Bruno Gauthier <bgauthier@free.fr> - 2011-08-07 07:53 +0200
    Re: Forth Performance Question Julian Fondren <ayrnieu@gmail.com> - 2011-08-07 01:01 -0500
    Re: Forth Performance Question Albert van der Horst <albert@spenarnc.xs4all.nl> - 2011-08-07 12:50 +0000
    Re: Forth Performance Question stephenXXX@mpeforth.com (Stephen Pelc) - 2011-08-07 11:46 +0000
    Re: Forth Performance Question Arnold Doray <thinksquared@gmail.com> - 2011-08-10 17:03 +0000
      Re: Forth Performance Question Julian Fondren <ayrnieu@gmail.com> - 2011-08-10 13:35 -0500
        Re: Forth Performance Question Arnold Doray <thinksquared@gmail.com> - 2011-08-11 15:05 +0000
          Re: Forth Performance Question anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2011-08-11 16:26 +0000
            Re: Forth Performance Question Arnold Doray <thinksquared@gmail.com> - 2011-08-12 08:15 +0000
              Re: Forth Performance Question "Elizabeth D. Rather" <erather@forth.com> - 2011-08-11 22:29 -1000
                Re: Forth Performance Question Arnold Doray <thinksquared@gmail.com> - 2011-08-12 10:09 +0000
                  Re: Forth Performance Question Julian Fondren <ayrnieu@gmail.com> - 2011-08-12 08:15 -0500
              Re: Forth Performance Question anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2011-08-12 09:31 +0000
          Re: Forth Performance Question crc <charles.childers@gmail.com> - 2011-08-11 10:27 -0700
          Re: Forth Performance Question Julian Fondren <ayrnieu@gmail.com> - 2011-08-11 13:18 -0500
          Re: Forth Performance Question "Elizabeth D. Rather" <erather@forth.com> - 2011-08-11 12:00 -1000
            Re: Forth Performance Question Howerd <howerdo@yahoo.co.uk> - 2011-08-11 15:13 -0700
            Re: Forth Performance Question Charles Childers <crc_nospam@retroforth.org> - 2011-08-11 20:52 -0400
            Re: Forth Performance Question "Rod Pemberton" <do_not_have@noavailemail.cmm> - 2011-08-12 02:19 -0400
              Re: Forth Performance Question Julian Fondren <ayrnieu@gmail.com> - 2011-08-12 02:10 -0500
                Re: Forth Performance Question "Elizabeth D. Rather" <erather@forth.com> - 2011-08-11 21:48 -1000
              Re: Forth Performance Question "Elizabeth D. Rather" <erather@forth.com> - 2011-08-11 21:41 -1000
      Re: Forth Performance Question Charles Childers <crc_nospam@retroforth.org> - 2011-08-10 23:33 -0400
        Re: Forth Performance Question Ron Aaron <rambamist@gmail.com> - 2011-08-11 08:59 +0300
        Re: Forth Performance Question Arnold Doray <thinksquared@gmail.com> - 2011-08-11 13:48 +0000
          Re: Forth Performance Question Charles Childers <crc@retroforth.org> - 2011-08-11 10:30 -0400
      Re: Forth Performance Question Ron Aaron <rambamist@gmail.com> - 2011-08-11 08:46 +0300
      Re: Forth Performance Question arc <arc@vorsicht-bissig.de> - 2011-08-12 12:20 +0000
        Re: Forth Performance Question Arnold Doray <thinksquared@gmail.com> - 2011-08-12 13:59 +0000
          Re: Forth Performance Question stephenXXX@mpeforth.com (Stephen Pelc) - 2011-08-12 15:11 +0000
            Re: Forth Performance Question Arnold Doray <thinksquared@gmail.com> - 2011-08-12 17:49 +0000
              Re: Forth Performance Question stephenXXX@mpeforth.com (Stephen Pelc) - 2011-08-12 19:38 +0000
              Re: Forth Performance Question "Elizabeth D. Rather" <erather@forth.com> - 2011-08-12 12:41 -1000
                Re: Forth Performance Question Arnold Doray <thinksquared@gmail.com> - 2011-08-13 03:35 +0000
                  Re: Forth Performance Question "Elizabeth D. Rather" <erather@forth.com> - 2011-08-12 17:52 -1000
                  Re: Forth Performance Question Paul Rubin <no.email@nospam.invalid> - 2011-08-12 23:55 -0700
                  Re: Forth Performance Question Albert van der Horst <albert@spenarnc.xs4all.nl> - 2011-08-14 09:01 +0000
                    Re: Forth Performance Question Paul Rubin <no.email@nospam.invalid> - 2011-08-14 01:36 -0700
                      Re: Forth Performance Question Arnold Doray <thinksquared@gmail.com> - 2011-08-15 01:43 +0000
                        Re: Forth Performance Question Hugh Aguilar <hughaguilar96@yahoo.com> - 2011-08-15 16:59 -0700
                          Re: Forth Performance Question Mark Wills <markrobertwills@yahoo.co.uk> - 2011-08-16 03:25 -0700
                            Re: Forth Performance Question Arnold Doray <thinksquared@gmail.com> - 2011-08-16 11:22 +0000
                              Re: Forth Performance Question Hugh Aguilar <hughaguilar96@yahoo.com> - 2011-08-16 14:37 -0700
                                Re: Forth Performance Question Arnold Doray <thinksquared@gmail.com> - 2011-08-19 14:11 +0000
                                  Re: Forth Performance Question Hugh Aguilar <hughaguilar96@yahoo.com> - 2011-08-22 19:52 -0700
              Re: Forth Performance Question Zbiggy <zbigniew2011REMOVE@gmail.REMOVE.com> - 2011-08-13 02:28 +0200
          Re: Forth Performance Question Zbiggy <zbigniew2011REMOVE@gmail.REMOVE.com> - 2011-08-12 20:53 +0200

Page 1 of 3  [1] 2 3  Next page →


#4626 — Forth Performance Question

FromTS <thinksquared@gmail.com>
Date2011-08-06 20:43 -0700
SubjectForth Performance Question
Message-ID<f0fc528e-2fdb-42af-a66d-976ebfa73b88@c8g2000prn.googlegroups.com>
Hi,

I'm just starting to learn Forth, and trying to assess the performance
differences between some of the common free Forths. I ran this
program:

: foo  1 1000000 * drop ;
: test 1 100000000 ?DO foo LOOP ;

On BigForth 2.4.0 it took ~22 sec to run, Retro v11 (with "times"
syntax, compiled with -O3), took ~23 sec and GForth 0.7.0 ~65 sec to
run.

I also tried to compare these numbers with Java (Sun, 1.6), assuming
that since it also uses a stack based VM, I would get comparable
performance:

public class Test {
	public static void main(String[] args) {
		for(int i = 0; i < 100000000; ++i){
			foo();
		}
	}
	private static final int foo(){
		return 1*1000000;
	}
}

Which did it in less than a second (!). I've tried variations on the
Java program (eg, creating a local variable x to act as a counter
instead of calling foo(), and the timing is always still less than a
second.

I'm using Ubuntu  (64 bit).and GCC 4.4.3 on an Intel Core2 Duo laptop.

I have two main questions:

a) Since BigForth is compiles to native code, why is its performance
similar to Retro, which is interpreted?

b) Why the enormous difference in speed between Java (which is also
based on a stack VM) and these Forths? Is it because the JIT performs
inlining? Or might there be other reasons?

Thanks,
TS

[toc] | [next] | [standalone]


#4627

From"Rod Pemberton" <do_not_have@noavailemail.cmm>
Date2011-08-07 01:02 -0400
Message-ID<j1l69n$vvj$1@speranza.aioe.org>
In reply to#4626
"TS" <thinksquared@gmail.com> wrote in message
news:f0fc528e-2fdb-42af-a66d-976ebfa73b88@c8g2000prn.googlegroups.com...
>
> I'm just starting to learn Forth, and trying to assess the performance
> differences between some of the common free Forths. I ran this
> program:
>
> : foo  1 1000000 * drop ;
> : test 1 100000000 ?DO foo LOOP ;
>
> On BigForth 2.4.0 it took ~22 sec to run, Retro v11 (with "times"
> syntax, compiled with -O3), took ~23 sec and GForth 0.7.0 ~65 sec to
> run.
>
> I also tried to compare these numbers with Java (Sun, 1.6), assuming
> that since it also uses a stack based VM, I would get comparable
> performance:
>
> public class Test {
> public static void main(String[] args) {
> for(int i = 0; i < 100000000; ++i){
> foo();
> }
> }
> private static final int foo(){
> return 1*1000000;
> }
> }
>
> Which did it in less than a second (!). I've tried variations on the
> Java program (eg, creating a local variable x to act as a counter
> instead of calling foo(), and the timing is always still less than a
> second.
>

I'd guess that's much closer to optimized C performance.  Java is C a
derived language ...  So, my guess is that Java has a very good optimizing
compiler.  That looks like C++ code to me ...  Have to tried compiling C++
or the C equivalent and timing it?

I'd also guess that "expensive" Forth-like stack manipulations are not used
even though Java uses a "stack based VM".   Since it's C derived, Java
probably is not a "stack based language" like Forth even if it's using a
"stack based VM".  If my guesses are true, that would mean Java is 1) not
interpreted (slow) 2) very optimized (fast) 3) preferences registers to
stack (faster) when compiled and 4) uses the stack very wisely (not as
slow).

> I'm using Ubuntu  (64 bit).and GCC 4.4.3 on an Intel Core2 Duo laptop.
>
> I have two main questions:
>
> a) Since BigForth is compiles to native code, why is its performance
> similar to Retro, which is interpreted?
>

Just because the code compiles to native code doesn't mean the resulting
code is very different in structure, speed, optimization from the Forth's
non-compiled implementation.  It just means that it's compiled, and native
code.  I.e., it could basically be identical to the non-compiled code after
parsing of the Forth text.

E.g., my Forth interpreter is in C.  I could take the C code for the Forth
words I consider to be an "application" and compile them as a dedicated app
with the interpreter code which is also in C.  Result?  The code is
compiled, interpreted, and has some optimization by the C compiler.
However, the code is not well written C code.  The C code has not been
written by hand for good performance when compiled.  It's just Forth emitted
as C, compileable as C, and the compiler optimizes what it can.  If I wrote
or rewrote the same app in C, it'd compile to much faster code without any
optimization because it'd be well written C (presumptively).

> b) Why the enormous difference in speed between Java (which is also
> based on a stack VM) and these Forths? Is it because the JIT performs
> inlining? Or might there be other reasons?
>

Above ...


Rod Pemberton


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


#4980

FromChris Hinsley <chris.hinsley@gmail.com>
Date2011-08-16 12:09 +0100
Message-ID<2011081612094679612-chrishinsley@gmailcom>
In reply to#4627
On 2011-08-07 05:02:39 +0000, Rod Pemberton said:



<snip>

But stack locations are the same speed of accsess as registers on a 
modern CPU design ? That's what the CPU companies spend all there time 
on.

So why do stack machines like Forth run so slow compared to Java ?

I still don't see an adaquate responce to this question ?

Chris

ps. Has anyone written a dynamic traceing Jit for Forth ?
pps. Would it make any difference if someone did ?

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


#4983

FromstephenXXX@mpeforth.com (Stephen Pelc)
Date2011-08-16 14:08 +0000
Message-ID<4e4a7805.100800092@192.168.0.50>
In reply to#4980
On Tue, 16 Aug 2011 12:09:46 +0100, Chris Hinsley
<chris.hinsley@gmail.com> wrote:

>So why do stack machines like Forth run so slow compared to Java ?

They don't when properly implemented. According to the MPE
benchmarks, the top three for performance are (within 15%
of each other)
  VFX Forth
  iForth
  nxt/lf

See:
  http://www.mpeforth.com/arena/benchmrk.fth

>ps. Has anyone written a dynamic traceing Jit for Forth ?
>pps. Would it make any difference if someone did ?

How ever much code do you want to compile? On a 2GHz Core2 Duo
we generate binary at about 500kb/sec.

Stephen


-- 
Stephen Pelc, stephenXXX@mpeforth.com
MicroProcessor Engineering Ltd - More Real, Less Time
133 Hill Lane, Southampton SO15 5AF, England
tel: +44 (0)23 8063 1441, fax: +44 (0)23 8033 9691
web: http://www.mpeforth.com - free VFX Forth downloads

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


#4628

Frommhx@iae.nl (Marcel Hendrix)
Date2011-08-07 07:45 +0200
Message-ID<14589696958436@frunobulax.edu>
In reply to#4626
TS <thinksquared@gmail.com> wrote Re: Forth Performance Question

> Hi,

> I'm just starting to learn Forth, and trying to assess the performance
> differences between some of the common free Forths. I ran this
> program:

> : foo  1 1000000 * drop ;
> : test 1 100000000 ?DO foo LOOP ;

This "test: probably doesn't do what you think it does. It wouldn't
matter when used to compare 32-bit Forths, but it does when comparing
Forth to Java. What you probably intended is

: test 100000000 0 ?DO foo LOOP ;

> On BigForth 2.4.0 it took ~22 sec to run, Retro v11 (with "times"
> syntax, compiled with -O3), took ~23 sec and GForth 0.7.0 ~65 sec to
> run.

It is valid to compare the two Forths, given they are both either 
32-bits or 64-bits.

[..]

> I'm using Ubuntu  (64 bit).and GCC 4.4.3 on an Intel Core2 Duo laptop.

> I have two main questions:

> a) Since BigForth is compiles to native code, why is its performance
> similar to Retro, which is interpreted?

> public class Test {
>	public static void main(String[] args) {
>		for(int i = 0; i < 100000000; ++i){
>			foo();
>		}
>	}
>	private static final int foo(){
>		return 1*1000000;
>	}
> }

The compiler will not produce code for 1*1000000 (it's a constant), 
and therefore the foo() function is inlined in main. Inlining
probably doesn't even happen because the efect of foo() can not
be observed outside the for loop. In that case the JIT may not even
compile the loop, and your only measuring the startup time of the
code. To do a true comparison you need multiply not 1 and 1000000,
but a and b, where a and b are integer arguments to main (so the JIT
can not predict what they are).

In Forth, the test word is not strictly interpreted. (It is better 
to read up a bit on Forth before attempting to benchmark.)

A classical DO LOOP has very little overhead that can be optimized 
away. And it is a stretch to call Retro "classical."

> b) Why the enormous difference in speed between Java (which is also
> based on a stack VM) and these Forths? Is it because the JIT performs
> inlining? Or might there be other reasons?

Here is Forth code which functionally matches your intention(?):

( Run on a 64-bit nc Forth, Windows 7 64bit, Intel Core i7 920, 2.67 GHz)
FORTH> : foo  1 1000000 * drop ; 
FORTH> \ : test 1 100000000 ?DO foo LOOP ; 
: test cr timer-reset 100000000 1 ?DO foo LOOP .elapsed ;
FORTH> test
0.219 seconds elapsed. ok

This puzzle does not exist. 

-marcel

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


#4640

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2011-08-07 16:18 +0000
Message-ID<2011Aug7.181837@mips.complang.tuwien.ac.at>
In reply to#4628
mhx@iae.nl (Marcel Hendrix) writes:
>TS <thinksquared@gmail.com> wrote Re: Forth Performance Question
>> public class Test {
>>	public static void main(String[] args) {
>>		for(int i = 0; i < 100000000; ++i){
>>			foo();
>>		}
>>	}
>>	private static final int foo(){
>>		return 1*1000000;
>>	}
>> }
>
>The compiler will not produce code for 1*1000000 (it's a constant), 
>and therefore the foo() function is inlined in main. Inlining
>probably doesn't even happen because the efect of foo() can not
>be observed outside the for loop. In that case the JIT may not even
>compile the loop, and your only measuring the startup time of the
>code. To do a true comparison you need multiply not 1 and 1000000,
>but a and b, where a and b are integer arguments to main (so the JIT
>can not predict what they are).

Even that would probably be optimized away completely, because foo()
has no side effects and its result is thrown away.  Even if you
eliminate that, multiplying an loop-invariant a and b produces a
loop-invariant result, so the optimizer will likely produce code that
performs only one multiplication.

Better write a program that does something slightly useful; it's less
likely that the compiler can optimize that into oblivion.

- anton
-- 
M. Anton Ertl  http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
     New standard: http://www.forth200x.org/forth200x.html
   EuroForth 2011: http://www.euroforth.org/ef11/

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


#4629

FromBruno Gauthier <bgauthier@free.fr>
Date2011-08-07 07:53 +0200
Message-ID<4e3e2877$0$10769$426a74cc@news.free.fr>
In reply to#4626
Le 07/08/2011 05:43, TS a écrit :
> Hi,
>
> I'm just starting to learn Forth, and trying to assess the performance
> differences between some of the common free Forths. I ran this
> program:
>
> : foo  1 1000000 * drop ;
> : test 1 100000000 ?DO foo LOOP ;
>
> On BigForth 2.4.0 it took ~22 sec to run, Retro v11 (with "times"
> syntax, compiled with -O3), took ~23 sec and GForth 0.7.0 ~65 sec to
> run.
>
> I also tried to compare these numbers with Java (Sun, 1.6), assuming
> that since it also uses a stack based VM, I would get comparable
> performance:
>
> public class Test {
> 	public static void main(String[] args) {
> 		for(int i = 0; i<  100000000; ++i){
> 			foo();
> 		}
> 	}
> 	private static final int foo(){
> 		return 1*1000000;
> 	}
> }
>
> Which did it in less than a second (!). I've tried variations on the
> Java program (eg, creating a local variable x to act as a counter
> instead of calling foo(), and the timing is always still less than a
> second.
>
> I'm using Ubuntu  (64 bit).and GCC 4.4.3 on an Intel Core2 Duo laptop.
>
> I have two main questions:
>
> a) Since BigForth is compiles to native code, why is its performance
> similar to Retro, which is interpreted?
>
> b) Why the enormous difference in speed between Java (which is also
> based on a stack VM) and these Forths? Is it because the JIT performs
> inlining? Or might there be other reasons?
>
> Thanks,
> TS
hi TS,
Its because your code is wrong !
test should be writen :
: test 100000000 1 ?do foo loop ;
or : test 1 100000000 ?do foo -1 +loop ;



bruno



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


#4630

FromJulian Fondren <ayrnieu@gmail.com>
Date2011-08-07 01:01 -0500
Message-ID<86r54x4v6g.fsf@gmail.com>
In reply to#4626
TS <thinksquared@gmail.com> writes:

> Hi,

(This guy's posting from Google Groups, a web interface for Usenet run
by a company that's too inept even to announce to their own users that
their service is having problems.  I already sent him an email to warn
him to look for replies in other venues.)

> I'm just starting to learn Forth, and trying to assess the performance
> differences between some of the common free Forths. I ran this
> program:

> : foo  1 1000000 * drop ;
> : test 1 100000000 ?DO foo LOOP ;
>
> On BigForth 2.4.0 it took ~22 sec to run, Retro v11 (with "times"
> syntax, compiled with -O3), took ~23 sec and GForth 0.7.0 ~65 sec to
> run.

bigForth et al actually do the work at run-time, because you told them
to.  Java may have noticed that the entire program is a no-op.  GCC
certainly can:

  $ cat opt.c
  int main (void) { int i; for (i = 0; i < 999999; i++); return 0; }
  $ gcc -O3 -S opt.c
  $ cat opt.s
          .file   "opt.c"
          .section        .text.startup,"ax",@progbits
          .p2align 4,,15
          .globl  main
          .type   main, @function
  main:
  .LFB0:
          .cfi_startproc
          xorl    %eax, %eax
          ret
          .cfi_endproc
  .LFE0:
          .size   main, .-main
          .ident  "GCC: (GNU) 4.6.0 20110603 (Red Hat 4.6.0-10)"
          .section        .note.GNU-stack,"",@progbits

That's it.  See any loops in that?

If your programs need to do a lot of work that can be done at
compile-time, or that reduce to nothing, of the two languages, only
Forth lets you do this explicitly, and very naturally; you don't have
to hope that an optimizer will notice.

> a) Since BigForth is compiles to native code, why is its performance
> similar to Retro, which is interpreted?

Your _benchmark_ doesn't highlight any differences.  A benchmark that
gave native code more to do, might do better.  A real program should do
better.

Although, I'm not equipped even to agree that Retro is interpreted.
It's one of those defiantly non-ANS Forth-reminiscent languages.

http://en.wikipedia.org/wiki/Software_rot#Example

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


#4637

FromAlbert van der Horst <albert@spenarnc.xs4all.nl>
Date2011-08-07 12:50 +0000
Message-ID<lpk6bg.3mh@spenarnc.xs4all.nl>
In reply to#4626
In article <f0fc528e-2fdb-42af-a66d-976ebfa73b88@c8g2000prn.googlegroups.com>,
TS  <thinksquared@gmail.com> wrote:
>Hi,
>
>I'm just starting to learn Forth, and trying to assess the performance
>differences between some of the common free Forths. I ran this
>program:
>
>: foo  1 1000000 * drop ;
>: test 1 100000000 ?DO foo LOOP ;

This is a bad benchmark. An optimiser can reduce it to nought.

>
>On BigForth 2.4.0 it took ~22 sec to run, Retro v11 (with "times"
>syntax, compiled with -O3), took ~23 sec and GForth 0.7.0 ~65 sec to
>run.
>
>I also tried to compare these numbers with Java (Sun, 1.6), assuming
>that since it also uses a stack based VM, I would get comparable
>performance:
>
>public class Test {
>       public static void main(String[] args) {
>               for(int i = 0; i < 100000000; ++i){
>                       foo();
>               }
>       }
>       private static final int foo(){
>               return 1*1000000;
>       }
>}
>
>Which did it in less than a second (!). I've tried variations on the
>Java program (eg, creating a local variable x to act as a counter
>instead of calling foo(), and the timing is always still less than a
>second.

Apparently a decent optimiser. Don't be surprised if you get a
similar result with iforth.

>
>I'm using Ubuntu  (64 bit).and GCC 4.4.3 on an Intel Core2 Duo laptop.
>
>I have two main questions:
>
>a) Since BigForth is compiles to native code, why is its performance
>similar to Retro, which is interpreted?
>
>b) Why the enormous difference in speed between Java (which is also
>based on a stack VM) and these Forths? Is it because the JIT performs
>inlining? Or might there be other reasons?

See above, optimiser.

>
>Thanks,
>TS


--
-- 
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- being exponential -- ultimately falters.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

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


#4638

FromstephenXXX@mpeforth.com (Stephen Pelc)
Date2011-08-07 11:46 +0000
Message-ID<4e3e7776.231242091@192.168.0.50>
In reply to#4626
On Sat, 6 Aug 2011 20:43:22 -0700 (PDT), TS <thinksquared@gmail.com>
wrote:

>: foo  1 1000000 * drop ;
>: test 1 100000000 ?DO foo LOOP ;

That should be
  : test 100000000 1 ?DO foo LOOP ;

>On BigForth 2.4.0 it took ~22 sec to run, Retro v11 (with "times"
>syntax, compiled with -O3), took ~23 sec and GForth 0.7.0 ~65 sec to
>run.
>
>I also tried to compare these numbers with Java (Sun, 1.6), assuming
>that since it also uses a stack based VM, I would get comparable
>performance:
>
>public class Test {
>	public static void main(String[] args) {
>		for(int i = 0; i < 100000000; ++i){
>			foo();
>		}
>	}
>	private static final int foo(){
>		return 1*1000000;
>	}
>}
>
>Which did it in less than a second (!). I've tried variations on the
>Java program (eg, creating a local variable x to act as a counter
>instead of calling foo(), and the timing is always still less than a
>second.
>
>I'm using Ubuntu  (64 bit).and GCC 4.4.3 on an Intel Core2 Duo laptop.
>
>I have two main questions:
>
>a) Since BigForth is compiles to native code, why is its performance
>similar to Retro, which is interpreted?
>
>b) Why the enormous difference in speed between Java (which is also
>based on a stack VM) and these Forths? Is it because the JIT performs
>inlining? Or might there be other reasons?

First, let's normalise so that Forth is doing what was intended. This
is VFX Forth for Windows on a 2.0GHz Core2 Duo.

: foo  1 1000000 * drop ;  ok
: test 1 100000000 ?DO foo LOOP ;  ok
test  ok
dis test 
TEST 
( 004C6DF0    681F6E4C00 )            PUSH      004C6E1F
( 004C6DF5    68FFE0F585 )            PUSH      85F5E0FF
( 004C6DFA    6800E1F505 )            PUSH      05F5E100
( 004C6DFF    817C240400000080 )      CMP       [ESP+04], 80000000
( 004C6E07    7505 )                  JNZ/NE    004C6E0E
( 004C6E09    8D642408 )              LEA       ESP, [ESP+08]
( 004C6E0D    C3 )                    NEXT,
( 004C6E0E    90 )                    NOP
( 004C6E0F    90 )                    NOP
( 004C6E10    83042401 )              ADD       [ESP], 01
( 004C6E14    8344240401 )            ADD       [ESP+04], 01
( 004C6E19    71F5 )                  JNO       004C6E10
( 004C6E1B    8D64240C )              LEA       ESP, [ESP+0C]
( 004C6E1F    C3 )                    NEXT,
( 48 bytes, 14 instructions )
 ok
timer-reset test .elapsed 12761 ms elapsed ok

The compiler noted that FOO does nothing, generated a compile-time
literal, and discarded it at compile time.

dis foo 
FOO 
( 004C6DD0    C3 )                    NEXT,
( 1 bytes, 1 instructions )

The tokeniser is still active, so nothing was compiled when FOO
was compiled.

That was running the loop the wrong way. Now change it.

: test 100000000 1 ?DO foo LOOP ; 
TEST is redefined  ok
timer-reset test .elapsed 359 ms elapsed ok

Note that DO ... LOOP affects the return stack and is not necessarily
the fastest counted loop.

: test2  100000000 begin  foo  1- dup 0= until drop ;  ok
dis test2 
TEST2 
( 004C6E40    8D6DFC )                LEA       EBP, [EBP+-04]
( 004C6E43    895D00 )                MOV       [EBP], EBX
( 004C6E46    BB00E1F505 )            MOV       EBX, 05F5E100
( 004C6E4B    90 )                    NOP
( 004C6E4C    90 )                    NOP
( 004C6E4D    90 )                    NOP
( 004C6E4E    90 )                    NOP
( 004C6E4F    90 )                    NOP
( 004C6E50    4B )                    DEC       EBX
( 004C6E51    85DB )                  TEST      EBX, EBX
( 004C6E53    75FB )                  JNZ/NE    004C6E50
( 004C6E55    8B5D00 )                MOV       EBX, [EBP]
( 004C6E58    8D6D04 )                LEA       EBP, [EBP+04]
( 004C6E5B    C3 )                    NEXT,
( 28 bytes, 14 instructions )
 ok
timer-reset test2 .elapsed 78 ms elapsed ok

The loop activity now happens entirely in registers and saves four
memory accesses.

Stephen


-- 
Stephen Pelc, stephenXXX@mpeforth.com
MicroProcessor Engineering Ltd - More Real, Less Time
133 Hill Lane, Southampton SO15 5AF, England
tel: +44 (0)23 8063 1441, fax: +44 (0)23 8033 9691
web: http://www.mpeforth.com - free VFX Forth downloads

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


#4692

FromArnold Doray <thinksquared@gmail.com>
Date2011-08-10 17:03 +0000
Message-ID<j1udl9$el4$1@dont-email.me>
In reply to#4626
Thank you for your replies. Yes, I made a mistake in my ANS Forth test. I 
see now that:

: test 0 100000000 ?DO foo LOOP ; 

simply increments the second parameter until integer overflow occurs, 
which makes it coincide with the first argument, stopping the loop. Not 
what I had in mind at all. I re-ran the test putting the loop arguments 
in the right order: Gforth (<2sec) and BigForth (<1sec). 

Some of you had pointed out that this is not a good performance benchmark 
since: 

: foo 1 1000000 * drop ;

would be compiled to a noop. However, this is exactly what I had hoped 
would happen, and was dismayed (wrongly, of course) when it didn't. 

I am actually interested in Retro (small VM, which seems to be easy to 
extend; reasonably good documentation and IMO nice language coverage). In 
Retro, the correct loop syntax is:

: test 1 100000000 [ foo ] times ;

Reversing the order of the arguments causes the loop body not to execute. 
Exactly what a C/Java programmer would expect. IMO, while Retro might be 
"defiantly Non-ANS Forth compliant", its choice of syntax helps the C/
Java programmer into using Forth. 

Unfortunately, unless I am mistaken, Retro is slow: My test above shows 
that it is more than 10x slower than Gforth. 

I followed your suggestions to make a more realistic Java comparison:

public class Test {

	public static void main(String[] args) {
		int x = 0;
		for(int i = 100000000; i > 0 ; --i){
			x += foo(x);
		}	
		System.out.println(x);
	}
	
	private static final int foo(int x){
		return x - 2*x + x + 1;
	}
}

Which is still fast (<1sec). 

@Julian Fondren - thank you for the heads up on the broken Google. 

Cheers,
Arnold





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


#4695

FromJulian Fondren <ayrnieu@gmail.com>
Date2011-08-10 13:35 -0500
Message-ID<86zkjhjes4.fsf@gmail.com>
In reply to#4692
Arnold Doray <thinksquared@gmail.com> writes:

> I am actually interested in Retro (small VM, which seems to be easy to 
> extend; reasonably good documentation and IMO nice language coverage). In 
> Retro, the correct loop syntax is:
>
> : test 1 100000000 [ foo ] times ;
>
> Reversing the order of the arguments causes the loop body not to execute. 
> Exactly what a C/Java programmer would expect. IMO, while Retro might be 
> "defiantly Non-ANS Forth compliant", its choice of syntax helps the C/
> Java programmer into using Forth. 

Except, you aren't learning Forth.  You're learning Retro.  You
wouldn't've mixed up the arguments to DO .. LOOP if you had set out to
learn Forth; as a suggested barrier to Java programmers, that's just
absurd.

Forth is amazingly flexible, both ANS Forth and ANS Forth + a small
bundle of environmental dependencies.  You want DO with your own
argument order?

  : DO   postpone swap postpone DO ; immediate

You want TIMES ?

  : times ( u xt -- )
    swap 0 ?do dup >r execute r> loop drop ;

You want TIMES at compile time?

  : ]times ( u xt -- )
    swap 0 ?do dup compile, loop drop ; immediate

  : 8* ( n -- 8*n )  [ 3 ' 2* ]times ;

You want TIMES with a cute syntax?

  : call ( k -- ) >r ;
  \ : cont ( -- k ) r@ 2 cells + ;  \ gforth
  : cont ( -- k ) r@ 5 + ;  \ SF
  : { postpone cont postpone ahead ; immediate
  : } postpone exit postpone then ; immediate

  : times ( u k -- )
    swap 0 ?do dup >r call r> loop drop ;

  : test ( -- n )  5 5 { dup 2/ + } times ;

You don't gain any freedom by throwing Forth away; you just lose Forth.
It's like saying "I want to wear a neon pink cowboy hat, but people give
me dirty looks, so - rather than wear the hat and accept the looks -
I guess I'll just have to move to Zimbabwe."

>
> Unfortunately, unless I am mistaken, Retro is slow: My test above shows 
> that it is more than 10x slower than Gforth. 
>

gforth is more than faster.  It's also of a community with extremely
good commercial systems that you could very plausibly 'escape to' should
its performance become a problem.

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


#4735

FromArnold Doray <thinksquared@gmail.com>
Date2011-08-11 15:05 +0000
Message-ID<j20r39$edu$1@dont-email.me>
In reply to#4695
On Wed, 10 Aug 2011 13:35:23 -0500, Julian Fondren wrote:
> 
> Except, you aren't learning Forth.  You're learning Retro. You
> wouldn't've mixed up the arguments to DO .. LOOP if you had set out to
> learn Forth; as a suggested barrier to Java programmers, that's just
> absurd.

Wouldn't learning Scheme help one learn Lisp? ;) IMO, the Retro language 
set might be a comfortable introduction to Forth for programmers from a C/
Java background. 

The point of the DO...LOOP example wasn't that I got the arguments mixed 
up, but that the ANS Forth DO...LOOP is equivalent to:

for(int i = <start>; i = <end>; ++i){
  ...
}

Which most sane C/Java/Python/Ruby programmers would avoid due to the 
possibility of "start" exceeding "end" at the outset. The Retro "times" 
implementation matches exactly this reasonable cultural expectation. (I 
am curious -- is there a reason that ANS Forth does it this way?) 

This observation might seem pedantic to an experienced Forther, but it is 
hard for a beginner to deal with such "gotchas" at the start.

The Retro language reduces the Forth learning curve by meeting some of 
these cultural expectations. I don't know if it does this by sacrificing 
some of the expressive power of ANS Forth, which you amply demonstrate in 
your looping examples. 

> You don't gain any freedom by throwing Forth away; you just lose Forth.
> It's like saying "I want to wear a neon pink cowboy hat, but people give
> me dirty looks, so - rather than wear the hat and accept the looks - I
> guess I'll just have to move to Zimbabwe."

It's more like "I want to wear a neon pink cowboy hat, so I'll start by 
wearing a cowboy hat."

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


#4740

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2011-08-11 16:26 +0000
Message-ID<2011Aug11.182621@mips.complang.tuwien.ac.at>
In reply to#4735
Arnold Doray <thinksquared@gmail.com> writes:
>The point of the DO...LOOP example wasn't that I got the arguments mixed 
>up, but that the ANS Forth DO...LOOP is equivalent to:
>
>for(int i = <start>; i = <end>; ++i){
>  ...
>}

Another mixup: I guess you mean "i != <end>".

>Which most sane C/Java/Python/Ruby programmers would avoid due to the 
>possibility of "start" exceeding "end" at the outset. The Retro "times" 
>implementation matches exactly this reasonable cultural expectation. 

As Charles Childers wrote, that's not the case.

>(I 
>am curious -- is there a reason that ANS Forth does it this way?) 

You would have it do "i < <end>", right.  But which "<" would you use?
"<" or "u<"?

Of course, Gforth also provides the behaviour you want: write your
loop as

( nlimit nstart ) +DO ... LOOP

or 

( ulimit ustart ) U+DO ... LOOP

I don't recomment DO at all, because it does not behave like the C
loop above if <start>=<end>; the very least you should use is ?DO.

- anton
-- 
M. Anton Ertl  http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
     New standard: http://www.forth200x.org/forth200x.html
   EuroForth 2011: http://www.euroforth.org/ef11/

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


#4764

FromArnold Doray <thinksquared@gmail.com>
Date2011-08-12 08:15 +0000
Message-ID<j22nfl$ao3$1@dont-email.me>
In reply to#4740
On Thu, 11 Aug 2011 16:26:21 +0000, Anton Ertl wrote:
>>(I
>>am curious -- is there a reason that ANS Forth does it this way?)
> 
> You would have it do "i < <end>", right.  But which "<" would you use?
> "<" or "u<"?
> 
> Of course, Gforth also provides the behaviour you want: write your loop
> as
> 
> ( nlimit nstart ) +DO ... LOOP
> 
> or
> 
> ( ulimit ustart ) U+DO ... LOOP
> 
> 

Thank you. That was helpful.

> I don't recomment DO at all, because it does not behave like the C loop
> above if <start>=<end>; the very least you should use is ?DO.
> 
> 

I'm probably missing something, but I don't see why you recommend ?DO 
when it doesn't handle <start> < <end> ? (Gforth 0.7.0) :

test 0 1 ?DO 4 . LOOP ; ok
test 4444444...

+DO seems much more C-like:

: test +DO 4 . LOOP ; ok 
0 0 test  ok
1 0 test 4  ok
0 1 test  ok

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


#4765

From"Elizabeth D. Rather" <erather@forth.com>
Date2011-08-11 22:29 -1000
Message-ID<RJadnQfnT_7lednTnZ2dnUVZ_gCdnZ2d@supernews.com>
In reply to#4764
On 8/11/11 10:15 PM, Arnold Doray wrote:
> On Thu, 11 Aug 2011 16:26:21 +0000, Anton Ertl wrote:
...
>> I don't recomment DO at all, because it does not behave like the C loop
>> above if<start>=<end>; the very least you should use is ?DO.
>
> I'm probably missing something, but I don't see why you recommend ?DO
> when it doesn't handle<start>  <  <end>  ? (Gforth 0.7.0) :

There's a whole collection of "DO-ish" words for finite loops.  ?DO is 
useful because it handles the case where 0 0 DO would "run away".
DO ... <n> +LOOP is the most flexible, since it can run either up 
(towards larger positive numbers) or down, and by an arbitrary increment 
(possibly even a value computed inside the loop).  And, then, there are 
the BEGIN ... structures for indefinite loops.  Not to mention various 
non-Standard flavors. So there are words to manage whatever parameters a 
particular situation is designed for.

Cheers,
Elizabeth

-- 
==================================================
Elizabeth D. Rather   (US & Canada)   800-55-FORTH
FORTH Inc.                         +1 310.999.6784
5959 West Century Blvd. Suite 700
Los Angeles, CA 90045
http://www.forth.com

"Forth-based products and Services for real-time
applications since 1973."
==================================================

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


#4771

FromArnold Doray <thinksquared@gmail.com>
Date2011-08-12 10:09 +0000
Message-ID<j22u47$75g$1@dont-email.me>
In reply to#4765
On Thu, 11 Aug 2011 22:29:43 -1000, Elizabeth D. Rather wrote:
> There's a whole collection of "DO-ish" words for finite loops.  ?DO is
> useful because it handles the case where 0 0 DO would "run away". DO ...
> <n> +LOOP is the most flexible, since it can run either up (towards
> larger positive numbers) or down, and by an arbitrary increment
> (possibly even a value computed inside the loop).  And, then, there are
> the BEGIN ... structures for indefinite loops.  Not to mention various
> non-Standard flavors. So there are words to manage whatever parameters a
> particular situation is designed for.

Thanks. I am beginning to understand -- while in C-like languages you 
would simply change the "for" loop arguments, in Forth the programmer 
uses one of a number of loop constructs depending on the situation at 
hand or can simply fashion their own custom-made loop construct.

So, while in C it would be easy to understand what 

for(int i = x; i < 10; ++i){ ... } 

does, in Forth, you would have to remember what ?DO, +DO, U+DO and 
friends do on a case-by-case basis. 

Generalizing, this seems to imply that learning Forth requires a much 
greater effort than learning the basics of C-like languages - at least 
initially. It may also mean that beginners find it much harder to read 
practical Forth code, since they might not have a firm grasp of what a 
particular word does, and because you need quite a few of these (~100 ? 
from your other post). 

But even a newbie like myself can see the obvious benefits - first class 
functions, currying, continuations all out of the box, without any fancy 
syntax. Plus the flexibility to build pretty much any construct you need. 
And with runtimes that are <100KB in size. 

Pretty awesome.  

So perhaps a better way to learn Forth would be to learn a small subset 
of ANS Forth, rather than a stripped-down Forth-like variant language? 
Any pointers to what this subset would be? 

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


#4774

FromJulian Fondren <ayrnieu@gmail.com>
Date2011-08-12 08:15 -0500
Message-ID<86y5yy4vqf.fsf@gmail.com>
In reply to#4771
Arnold Doray <thinksquared@gmail.com> writes:

> So, while in C it would be easy to understand what 
>
> for(int i = x; i < 10; ++i){ ... } 
>
> does, in Forth, you would have to remember what ?DO, +DO, U+DO and 
> friends do on a case-by-case basis. 

You only have to know these words in the case that you're working on
code that uses them, in which case you can look them up simply enough.
For your own code, you don't need them; you only need DO .  Or rather,
you do not even need DO .  You only run the risk of having someone come
along to say "why don't you say <some more succint, more readable code
with a word you didn't use>", which is not so awful a fate.

Look:

  for (i = 0; i < 10; i++) ...;

is just a convenient expression for

  i = 0;
  while (i < 10) {
    ...
    i++;
  } 

Which is in Forth

  0 begin dup 10 < while ... 1+ repeat drop

DO and friends are likewise just convenient words, and especially aren't
a burden for a newbie who can avoid them in his own code.

> So perhaps a better way to learn Forth would be to learn a small subset 
> of ANS Forth, rather than a stripped-down Forth-like variant language? 
> Any pointers to what this subset would be? 

You don't need to understand every single word that your system
provides; therefore there's no need for a stripped-down system.  And ANS
Forth is _not_ big, so stripping that down is fairly pointless.  Get any
decent system, follow a tutorial maybe (I have fond memories of gforth's
"crash course"), and start learning the language.  At any given point
you'll know the subset that you know.  This is easier done than said.

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


#4769

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2011-08-12 09:31 +0000
Message-ID<2011Aug12.113143@mips.complang.tuwien.ac.at>
In reply to#4764
Arnold Doray <thinksquared@gmail.com> writes:
>On Thu, 11 Aug 2011 16:26:21 +0000, Anton Ertl wrote:
>> I don't recomment DO at all, because it does not behave like the C loop
>> above if <start>=<end>; the very least you should use is ?DO.
>> 
>> 
>
>I'm probably missing something, but I don't see why you recommend ?DO 
>when it doesn't handle <start> < <end> ? (Gforth 0.7.0) :

Did you mean <start> > <end>?

Anyway, ?DO handles <start> = <end>, and DO doesn't.  That's why ?DO
is better than DO.  And ?DO is standard, while +DO etc. are not
(however, there is a compatibility library that defines +DO etc. in
standard Forth: compat/loops.fs in
<http://www.complang.tuwien.ac.at/forth/compat.zip>.

- anton
-- 
M. Anton Ertl  http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
     New standard: http://www.forth200x.org/forth200x.html
   EuroForth 2011: http://www.euroforth.org/ef11/

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


#4745

Fromcrc <charles.childers@gmail.com>
Date2011-08-11 10:27 -0700
Message-ID<96ed95d2-07f7-4a99-b0f6-f3a1a09d127d@h7g2000yqm.googlegroups.com>
In reply to#4735
> The point of the DO...LOOP example wasn't that I got the arguments mixed
> up, but that the ANS Forth DO...LOOP is equivalent to:
>
> for(int i = <start>; i = <end>; ++i){
>   ...
>
> }
>
> Which most sane C/Java/Python/Ruby programmers would avoid due to the
> possibility of "start" exceeding "end" at the outset. The Retro "times"
> implementation matches exactly this reasonable cultural expectation.

Since Retro's "times" is a simple counted loop, it's still not quite
what you were aiming for. A better choice would be something like
"loop" (not part of the core language, but easy enough to implement:)

: loop ( seq- )
  [ 2rot 2over < [ [ [ [ &do sip ] dip ] dip 1- 2over < ] while ]
ifTrue 2drop drop ] , ; immediate

Or for one that increments the counter:

: loop ( seq- )
  [ 2rot 2over < [ [ [ [ &do sip ] dip 1+ ] dip 2over < ] while ]
ifTrue 2drop drop ] , ; immediate

With this, you'd pass a start and end as well as a quote. So this
would display and increment a value ten times:

: foo ( - )
  1  10 20 [ dup putn space 1+ ] loop  drop ;

-- crc

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


Page 1 of 3  [1] 2 3  Next page →

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


csiph-web