Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.forth > #4626 > unrolled thread
| Started by | TS <thinksquared@gmail.com> |
|---|---|
| First post | 2011-08-06 20:43 -0700 |
| Last post | 2011-08-12 20:53 +0200 |
| Articles | 20 on this page of 53 — 21 participants |
Back to article view | Back to comp.lang.forth
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 →
| From | TS <thinksquared@gmail.com> |
|---|---|
| Date | 2011-08-06 20:43 -0700 |
| Subject | Forth 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]
| From | "Rod Pemberton" <do_not_have@noavailemail.cmm> |
|---|---|
| Date | 2011-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]
| From | Chris Hinsley <chris.hinsley@gmail.com> |
|---|---|
| Date | 2011-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]
| From | stephenXXX@mpeforth.com (Stephen Pelc) |
|---|---|
| Date | 2011-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]
| From | mhx@iae.nl (Marcel Hendrix) |
|---|---|
| Date | 2011-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]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2011-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]
| From | Bruno Gauthier <bgauthier@free.fr> |
|---|---|
| Date | 2011-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]
| From | Julian Fondren <ayrnieu@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Albert van der Horst <albert@spenarnc.xs4all.nl> |
|---|---|
| Date | 2011-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]
| From | stephenXXX@mpeforth.com (Stephen Pelc) |
|---|---|
| Date | 2011-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]
| From | Arnold Doray <thinksquared@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Julian Fondren <ayrnieu@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Arnold Doray <thinksquared@gmail.com> |
|---|---|
| Date | 2011-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]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2011-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]
| From | Arnold Doray <thinksquared@gmail.com> |
|---|---|
| Date | 2011-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]
| From | "Elizabeth D. Rather" <erather@forth.com> |
|---|---|
| Date | 2011-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]
| From | Arnold Doray <thinksquared@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Julian Fondren <ayrnieu@gmail.com> |
|---|---|
| Date | 2011-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]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2011-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]
| From | crc <charles.childers@gmail.com> |
|---|---|
| Date | 2011-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