Mathematica 7 compares to other languages

D

Dimiter \malkia\ Stanev

You think the posts are bad... check out his web site...

Just don't go to every page on the Xah website - some of his stuff is
NSFW (Not Safe For Work).
 
X

Xah Lee

alright, here's my improved code, pasted near the bottom.

let me say a few things about Jon's code.

If we rate that piece of mathematica code on the level of: Beginner
Mathematica programer, Intermediate, Advanced, where Beginner is
someone who just learned tried to program Mathematica no more than 6
months, then that piece of code is Beginner level.

Here's some basic analysis and explanation.

The program has these main functions:

• RaySphere
• Intersect
• RayTrace
• Create
• Main

The Main calls Create then feed it to RayTrace.
Create calls itself recursively, and basically returns a long list of
a repeating element, each of the element differ in their parameter.

RayTrace calls Intersect 2 times. Intersect has 2 forms, one of them
calls itself recursively. Both forms calls RaySphere once.

So, the core loop is with the Intersect function and RaySphere. Some
99.99% of time are spent there.

------------------

I didn't realize until after a hour, that if Jon simply give numerical
arguments to Main and Create, the result timing by a factor of 0.3 of
original. What a incredible sloppiness! and he intended this to show
Mathematica speed with this code?

The Main[] function calls Create. The create has 3 parameters: level,
c, and r. The level is a integer for the recursive level of
raytracing . The c is a vector for sphere center i presume. The r is
radius of the sphere. His input has c and r as integers, and this in
Mathematica means computation with exact arithmetics (and automatic
kicks into infinite precision if necessary). Changing c and r to float
immediately reduced the timing to 0.3 of original.

------------------
now, back to the core loop.

The RaySphere function contain codes that does symbolic computation by
calling Im, which is the imaginary part of a complex number!! and if
so, it returns the symbol Infinity! The possible result of Infinity is
significant because it is used in Intersect to do a numerical
comparison in a If statement. So, here in these deep loops,
Mathematica's symbolic computation is used for numerical purposes!

So, first optimization at the superficial code form level is to get
rid of this symbolic computation.

Instead of checking whethere his “disc = Sqrt[b^2 - v.v + r^2]†has
imaginary part, one simply check whether the argument to sqrt is
negative.

after getting rid of the symbolic computation, i made the RaySphere
function to be a Compiled function.

I stopped my optimization at this step.

The above are some _fundamental_ things any dummy who claims to code
Mathematica for speed should know. Jon has written a time series
Mathematica package that he's selling commercially. So, either he got
very sloppy with this Mathematica code, or he intentionally made it
look bad, or that his Mathematica skill is truely beginner level. Yet
he dares to talk bullshit in this thread.

Besides the above basic things, there are several aspects that his
code can improve in speed. For example, he used pattern matching to do
core loops.
e.g. Intersect[o_, d_][{lambda_, n_}, Bound[c_, r_, s_]]

any Mathematica expert knows that this is something you don't want to
do if it is used in a core loop. Instead of pattern matching, one can
change the form to Function and it'll speed up.

Also, he used “Blockâ€, which is designed for local variables and the
scope is dynamic scope. However the local vars used in this are local
constants. A proper code would use “With†instead. (in lisp, this is
various let, let*. Lispers here can imagine how lousy the code is
now.)

Here's a improved code. The timing of this code is about 0.2 of the
original. Also, optimization is purely based on code doodling. That
is, i do not know what his code is doing, i do not have experience in
writing a ray tracer. All i did is eyeballing his code flow, and
improved the form.

norm=Function[#/Sqrt@(Plus@@(#^2))];
delta=Sqrt[$MachineEpsilon];
myInfinity=10000.;

Clear[RaySphere];
RaySphere = Compile[{o1, o2, o3, d1, d2, d3, c1, c2, c3, r},
Block[{v = {c1 - o1, c2 - o2, c3 - o3},
b = d1*(c1 - o1) + d2*(c2 - o2) + d3*(c3 - o3),
discriminant = -(c1 - o1)^2 - (c2 - o2)^2 +
(d1*(c1 - o1) + d2*(c2 - o2) + d3*(c3 - o3))^2 -
(c3 - o3)^2 + r^2, disc, t1, t2},
If[discriminant < 0., myInfinity,
disc = Sqrt[discriminant]; If[(t1 = b - disc) > 0.,
t1, If[(t2 = b + disc) <= 0., myInfinity, t2]]]]];

Remove[Intersect];
Intersect[{o1_,o2_,o3_},{d1_,d2_,d3_}][{lambda_,n_},Sphere
[{c1_,c2_,c3_},r_]]:=
Block[{lambda2=RaySphere[o1,o2,o3,d1,d2,d3,c1,c2,c3,r]},
If[lambda2≥lambda,{lambda,n},{lambda2,
norm[{o1,o2,o3}+lambda2 *{d1,d2,d3}-{c1,c2,c3}]}]]

Intersect[{o1_,o2_,o3_},{d1_,d2_,d3_}][{lambda_,n_},
Bound[{c1_,c2_,c3_},r_,s_]]:=
Block[{lambda2=RaySphere[o1,o2,o3,d1,d2,d3,c1,c2,c3,r]},
If[lambda2≥lambda,{lambda,n},
Fold[Intersect[{o1,o2,o3},{d1,d2,d3}],{lambda,n},s]]]

Clear[neglight,nohit]
neglight=N@norm[{1,3,-2}];
nohit={myInfinity,{0.,0.,0.}};

Clear[RayTrace];
RayTrace[o_,d_,scene_]:=
Block[{lambda,n,g,p},{lambda,n}=Intersect[o,d][nohit,scene];
If[lambda\[Equal]myInfinity,0,g=n.neglight;
If[g≤0,
0,{lambda,n}=Intersect[o+lambda d+delta n,neglight]
[nohit,scene];
If[lambda<myInfinity,0,g]]]]

Clear[Create];
Create[level_,c_,r_]:=
Block[{obj=Sphere[c,r]},
If[level\[Equal]1,obj,
Block[{a=3*r/Sqrt[12],Aux},
Aux[x1_,z1_]:=Create[level-1,c+{x1,a,z1},0.5 r];
Bound[c,3 r,{obj,Aux[-a,-a],Aux[a,-a],Aux[-a,a],Aux[a,a]}]
]
]]

Main[level_,n_,ss_]:=
With[{scene=Create[level,{0.,-1.,4.},1.]},
Table[Sum[
RayTrace[{0,0,0},
N@norm[{(x+s/ss/ss)/n-1/2,(y+Mod[s,ss]/ss)/
n-1/2,1}],scene],{s,0,
ss^2-1}]/ss^2,{y,0,n-1},{x,0,n-1}]]

Timing[Export["image.pgm",Graphics@Raster@Main[2,100,4.]]]


Note to those who have Mathematica.
Mathematica 6 has Normalize, but that's not in Mathematica 4, so i
cooked up above.
Also, Mathematica 6 has AbsoluteTiming, which is intended to be
equivalent if you use stop watch to measure timing. Mathematica 4 has
only Timing, which measures CPU time. My speed improvement is based on
Timing. But the same factor will shown when using Mathematica 6 too.

I'm pretty sure further speed up by 0.5 factor of above's timing is
possible. Within 2 more hours of coding.

Jon wrote:
«The Mathematica code is 700,000x slower so a 50% improvement will be
uninteresting. Can you make my Mathematica code five orders of
magnitude faster or not?»

If anyone pay me $300, i can try to make it whatever the level of F#
or OCaml's speed is as cited in Jon's website. (
http://www.ffconsultancy.com/languages/ray_tracer/index.html ).

Please write out or write to me the detail exactly what speed is
required in some precise terms. If i agree to do it, spec satisfaction
is guaranteed or your money back.

PS Thanks Thomas M Hermann. It was fun.

Xah
∑ http://xahlee.org/

☄
 
X

Xah Lee

For the interested, with MMA 6, on a Pentium 4 3.8Ghz:

The code that Jon posted:

Timing[Export["image-jon.pgm", Graphics@Raster@Main[2, 100, 4]]]
{80.565, "image-jon.pgm"}

The code that Xah posted:

Timing[Export["image-xah.pgm", Graphics@Raster@Main[2, 100, 4.]]]
{42.3186, "image-xah.pgm"}

So Xah's code is about twice as fast as Jon's code, on my computer.

The resulting files were identical (and both looked like pure white
images; I thought they'd be interesting!).

The result is not pure white images. They are ray traced spheres
stacked in some recursive way. Here's the output in both my and jon's
version: http://xahlee.org/xx/image.pgm

also, note that Mathematica 6 has the function Normalize builtin,
which is used in Jon's code deeply in the core. Normalize is not in
Mathematica 4, so i had to code it myself, in this line: “norm=Function
[#/Sqrt@(Plus@@(#^2))];â€. This possibly slow down my result a lot. You
might want to replace any call of “norm†in my program by the builtin
Normalize.

Also, each version of Mathematica has more optimizations. So, that
might explain why on v4 the speed factor is ~0.2 on my machine while
in v6 you see ~0.5.

My machine is OS X 10.4.x, PPC G5 1.9 Ghz.

-------------------------

let me take the opportunity to explain some high powered construct of
Mathematica.

Let's say for example, we want to write a function that takes a vector
(of linear algebra), and return a vector in the same direction but
with length 1. In linear algebar terminology, the new vector is called
the “normalized†vector of the original.

For those of you who don't know linear algebra but knows coding, this
means, we want a function whose input is a list of 3 elements say
{x,y,z}, and output is also a list of 3 elements, say {a,b,c}, with
the condition that

a = x/Sqrt[x^2+y^2+z^2]
b = y/Sqrt[x^2+y^2+z^2]
c = z/Sqrt[x^2+y^2+z^2]

For much of the history of Mathematica, normalize is not a builtin
function. It was introduced in v6, released sometimes in 2007. See
bottom of:
http://reference.wolfram.com/mathematica/ref/Normalize.html

Now, suppose our task is to write this function. In my code, you see
it is:

norm=Function[#/Sqrt@(Plus@@(#^2))];

let me explain how it is so succinct.

Mathematica's syntax support what's called FullForm, which is
basically a fully nested notation like lisp's. In fact, the
Mathematica compiler works with FullForm. The FullForm is not
something internal. A programer can type his code that way if he so
pleases.

in FullForm, the above expression is this:
Set[ norm, Function[ Times[Slot[1], Power[ Sqrt[ Apply[ Plus, Power
[ Slot[1], 2 ] ] ], -1 ] ] ]

Now, in this
norm=Function[#/Sqrt@(Plus@@(#^2))]

The “Function†is your lisper's “lambdaâ€. The “#†is the formal
parameter. So, in the outset we set “norm†to be a pure function.

Now, note that the “#†is not just a number, but can be any argument,
including vector of the form {x,y,z}. So, we see here that math
operations are applied to list entities directly. For example, in
Mathematica, {3,4,5}/2 returns {3/2,2,5/2} and {3,4,5}^2 returns
{9,16,25}.

In typical lang such as python, including lisp, you would have to map
the operation into each lisp elements instead.

The “Sqrt@...†is a syntax shortcut for “Sqrt[...]â€, and the
“Plus@@...†is a syntax shortcut for “Apply[Plus, ....]â€, which is
lisp's “funcallâ€. So, taking the above all together, the code for
“norm†given above is _syntactically equivalent_ to this:

norm=Function[ #/Sqrt[ Apply[Plus, #^2] ]]

this means, square the vector, add them together, take the square
root, then have the original vector divide it.

The “#†is in fact a syntax shortcut for “Slot[1]â€, meaning the first
formal parameter. The “=†is in fact a syntax shortcut for “Set[]â€.
The “^†is a shortcut for “Power[]â€, and the “/†is a shortcut for
“Power[..., -1]â€. Putting all these today, you can see how the code is
syntactically equivalent to the above nested FullFolm.

Note, that the “norm†as defined above works for any dimentional
vectors, i.e. list of any length.

In lisp, python, perl, etc, you'll have 10 or so lines. In C or Java,
you'll have 50 or hundreds lines.

For more detail on syntax, see:

• The Concepts and Confusions of Prefix, Infix, Postfix and Fully
Nested Notations
http://xahlee.org/UnixResource_dir/writ/notations.html

Xah
∑ http://xahlee.org/

☄
 
X

Xah Lee

For those interested in this Mathematica problem, i've now cleaned up
the essay with additional comments here:

• A Mathematica Optimization Problem
http://xahlee.org/UnixResource_dir/writ/Mathematica_optimization.html

The result and speed up of my code can be verified by anyone who has
Mathematica.

Here's some additional notes i added to the above that is not
previously posted.

-------------------------

Advice For Mathematica Optimization

Here's some advice for mathematica optimization, roughly from most
important to less important:

* Any experienced programer knows, that optimization at the
algorithm level is far more important than at the level of code
construction variation. So, make sure the algorithm used is good, as
opposed to doodling with your code forms. If you can optimize your
algorithm, the speed up may be a order of magnitude. (for example,
various algorithm for sorting algorithms↗ illustrates this.)

* If you are doing numerical computation, always make sure that
your input and every intermediate step is using machine precision.
This you do by making the numbers in your input using decimal form
(e.g. use “1.â€, “N[Pi]†instead of “1â€, “Piâ€). Otherwise Mathematica
may use exact arithmetics.

* For numerical computation, do not simply slap “N[]†into your
code. Because the intermediate computation may still be done using
exact arithmetic or symbolic computation.

* Make sure your core loop, where your calculation is repeated and
takes most of the time spent, is compiled, by using Compile.

* When optimizing speed, try to avoid pattern matching. If your
function is “f[x_]:= ...â€, try to change it to the form of “f=Function
[x,...]†instead.

* Do not use complicated patterns if not necessary. For example,
use “f[x_,y_]†instead of “f[x_][y_]â€.

------------------------------

....

Besides the above basic things, there are several aspects that his
code can improve in speed. For example, he used rather complicated
pattern matching to do intensive numerical computation part. Namely:

Intersect[o_, d_][{lambda_, n_}, Bound[c_, r_, s_]]
Intersect[o_, d_][{lambda_, n_}, Sphere[c_, r_]]

Note that the way the parameters of Intersect defined above is a
nested form. The code would be much faster if you just change the
forms to:

Intersect[o_, d_, {lambda_, n_}, Bound[c_, r_, s_]]
Intersect[o_, d_, {lambda_, n_}, Sphere[c_, r_]]

or even just this:

Intersect[o_, d_, lambda_, n_, c_, r_, s_]
Intersect[o_, d_, lambda_, n_, c_, r_]

Also, note that the Intersect is recursive. Namely, the Intersect
calls itself. Which form is invoked depends on the pattern matching of
the parameters. However, not only that, inside one of the Intersect it
uses Fold to nest itself. So, there are 2 recursive calls going on in
Intersect. Reducing this recursion to a simple one would speed up the
code possibly by a order of magnitude.

Further, if Intersect is made to take a flat sequence of argument as
in “Intersect[o_, d_, lambda_, n_, c_, r_, s_]â€, then pattern matching
can be avoided by making it into a pure function “Functionâ€.. And when
it is a “Functionâ€, then Intersect or part of it may be compiled with
Compile. When the code is compiled, the speed should be a order of
magnitude faster.

-----------------------------

Someone keeps claiming that Mathematica code is some “5 order of
magnitude slowerâ€. It is funny how the order of magnitude is
quantified. I'm not sure there's a standard interpretation other than
hyperbole.

There's a famous quote by Alan Perlis ( http://en.wikipedia.org/wiki/Alan_Perlis
) that goes:
“A Lisp programmer knows the value of everything, but the cost of
nothing.â€

this quote captures the nature of lisp in comparison to most other
langs at the time the quote is written. Lisp is a functional lang, and
in functional langs, the concept of values is critical, because any
lisp program is either a function definition or expression. Function
and expression act on values and return values. The values along with
definitions determines the program behavior. “the cost of nothingâ€
captures the sense that in high level langs, esp dynamic langs like
lisp, it's easy to do something, but it is more difficult to know the
algorithmic behavior of constructs. This is in contrast to langs like
C, Pascal, or modern lang like Java, where almost anything you write
in it is “fastâ€, simply forced by the low level nature of the lang.

In a similar way, Mathematica is far more higher level than any
existing lang, counting other so-called computer algebra systems. A
simple one-liner Mathematica construct easily equates to 10 or hundred
lines of lisp, perl, python, and if you count its hundreds of
mathematical functions such as Solve, Derivative, Integrate, each line
of code is equivalent to a few thousands lines in other langs.

However, there is a catch, that applies to any higher level langs,
namely, it is extremely easy, to create a program that are very
inefficient.

This can typically be observed in student or beginner's code in lisp.
The code may produce the right output, but may be extremely
inefficient for lacking expertise with the language.

The phenomenon of creating code that are inefficient is proportional
to the highlevelness or power of the lang. In general, the higher
level of the lang, the less possible it is actually to produce a code
that is as efficient as a lower level lang. For example, the level or
power of lang can be roughly order as this:

assembly langs
C, pascal
C++, java, c#
unix shells
perl, python, ruby, php
lisp
Mathematica

the lower level the lang, the longer it consumes programer's time, but
faster the code runs. Higher level langs may or may not be crafted to
be as efficient. For example, code written in the level of langs such
as perl, python, ruby, will never run as fast as C, regardless what
expert a perler is. C code will never run as fast as assembler langs.
And if the task crafting a raytracing software, then perl, python,
ruby, lisp, Mathematica, are simply not suitable, and are not likely
to produce any code as fast as C or Java.

On the other hand, higher level langs in many applications simply
cannot be done with lower level lang for various practical reasons.
For example, you can use Mathematica to solve some physics problem in
few hours, or give Pi to gazillion digits in few seconds with just “N
[Pi,10000000000000]â€. Sure, you can code a solution in lisp, perl, or
even C, but that means few years of man hours. Similarly, you can do
text processing in C, Java, but perl, python, ruby, php, emacs lisp,
Mathematica, can reduce your man hours to 10% or 1% of coding effort.

In the above, i left out functional langs that are roughly statically
typed and compiled, such as Haskell, OCaml, etc. I do not have
experience with these langs. I suppose they do maitain some advantage
of low level lang's speed, yet has high level constructs. Thus, for
computationally intensive tasks such as writing a raytracer, they may
compete with C, Java in speed, yet easier to write with fewer lines of
code.

personally, i've made some effort to study Haskell but never went thru
it. In my experience, i find langs that are (roughly called) strongly
typed, difficult to learn and use. (i have reading knowledge of C and
working knowledge of Java, but am never good with Java. The verbosity
in Java turns me off thoroughly.)

-----------------

as to how fast Mathematica can be in the raytracing toy code shown in
this thread, i've given sufficient demonstration that it can be speed
up significantly. Even Mathematica is not suitable for this task, but
i'm pretty sure can make the code's speed in the some level of speed
as OCaml.
(as opposed to someone's claim that it must be some 700000 times
slower or some “5 orders of magnituted slowerâ€). However, to do so
will take me half a day or a day of coding. Come fly $300 to my paypal
account, then we'll talk. Money back guaranteed, as i said before.

Xah
∑ http://xahlee.org/

☄
 
X

Xah Lee

Xah said:
For those interested in this Mathematica problem, i've now cleaned up
the essay with additional comments here:

In that article you say:
Further, if Intersect is made to take a flat sequence of argument as
in “Intersect[o_, d_, lambda_, n_, c_, r_, s_]â€, then pattern matching can
be avoided by making it into a pure function “Functionâ€.. And when it is
a “Functionâ€, then Intersect or part of it may be compiled with Compile.
When the code is compiled, the speed should be a order of magnitude
faster.
That is incorrect. Mathematica's Compile function cannot handle recursive
functions like Intersect.

i didn't claim it can. You can't expect to have a fast or good program
if you code Java style in a functional lang.

Similarly, if you want code to run fast in Mathematica, you don't just
slap in your OCaml code into Mathematica syntax and expect it to work
fast.

If you are a Mathematica expert, you could make it recurse yet have
the speed as other langs. First, by changing your function's form, to
avoid pattern matching, and rewrite your bad recursion. That is what i
claimed in the above paragraph. Read it again to see.
For example:
In[1]:= Compile[{n_, _Integer}, If[# == 0, 1, #0[[# n - 1]] #1] &[n]]

During evaluation of In[1]:= Compile::fun: Compilation of
(If[#1==0,1,#0[[#1 n-1]] #1]&)[Compile`FunctionVariable$435] cannot
proceed. It is not possible to compile pure functions with arguments
that represent the function itself. >>

Mathematica's Compile function is intended to speed up numerical
computation. To want Compile to handle recursion in the context of
Mathematica's programing features, is not something possible even in
theoretical sense.

Scheme lisp implementations can compile recursive code, but lisp is a
lower level lang than Mathematica, where perhaps the majority of
Mathematica's builtin functions can equate to 10 or more lines of
lisp, and any of its hundreds math functions equates to entire
libraries of other langs. It is reasonable, but silly, to expect
Mathematica's Compile function to compile any code in Mathematica.

Perhaps in the future version of Mathematica, its Compile function can
handle basic recursive forms.

Also, in this discussion, thanks to Thomas M Hermann's $20 offered to
me for my challenge to you, that i have taken the time to show working
code that demonstrate many problems in your code. Unless you think my
code and replies to you are totally without merit or fairness, but
otherwise you should acknowledge it, in whole or in parts you agree,
in a honest and wholehearted way, instead of pushing on with petty
verbal fights.

Xah
∑ http://xahlee.org/

☄
 
X

Xah Lee

2008-12-08


You failed the challenge that you were given.

you didn't give me a challenge. I gave you. I asked for $5 sincerity
wage of mutal payment or money back guarantee, so that we can show
real code instead of verbal fight. You didn't take it and do nothing
but continue petty quarrel on words. Thomas was nice to pay me, which
results in my code that is demonstratably faster than yours. (verified
by a post from “jason-sage @@@ creativetrax.comâ€, quote: “So Xah's
code is about twice as fast as Jon's code, on my computer.â€, message
can be seen at “ http://www.gossamer-threads.com/lists/python/python/698196?do=post_view_threaded#698196
†) You refuse to acknowledge it, and continue babbling, emphasizing
that my code should be some hundred times faster make valid argument.

As i said, now pay me $300, i will then make your Mathematica code in
the same level of speed as your OCmal. If it does not, money back
guaranteed. Here's more precise terms i ask:

Show me your OCmal code that will compile on my machine (PPC Mac, OSX
10.4.x). I'll make your Mathematica code in the same speed level as
your OCmal code. (you claimed Mathematica is roughly 700 thousand
times slower to your OCmal code. I claim, i can make it, no more than
10 times slower than the given OCmal code.)

So, pay me $300 as consulting fee. If the result does not comply to
the above spec, money back guaranteed.
You should accept the fact that Mathematica currently has these
insurmountable limitations.

insurmountable ur mom.

Xah
∑ http://xahlee.org/

☄
 
G

George Neuner

The phenomenon of creating code that are inefficient is proportional
to the highlevelness or power of the lang. In general, the higher
level of the lang, the less possible it is actually to produce a code
that is as efficient as a lower level lang.

This depends on whether someone has taken the time to create a high
quality optimizing compiler.

For example, the level or power of lang can be roughly order as
this:

assembly langs
C, pascal
C++, java, c#
unix shells
perl, python, ruby, php
lisp
Mathematica

According to what "power" estimation? Assembly, C/C++, C#, Pascal,
Java, Python, Ruby and Lisp are all Turing Complete. I don't know
offhand whether Mathematica is also TC, but if it is then it is at
most equally powerful.

Grammatic complexity is not exactly orthogonal to expressive power,
but it is mostly so. Lisp's SEXPRs are an existence proof that a
Turing powerful language can have a very simple grammar. And while a
2D symbolic equation editor may be easier to use than spelling out the
elements of an equation in a linear textual form, it is not in any
real sense "more powerful".

the lower level the lang, the longer it consumes programer's time, but
faster the code runs. Higher level langs may or may not be crafted to
be as efficient. For example, code written in the level of langs such
as perl, python, ruby, will never run as fast as C, regardless what
expert a perler is.

There is no language level reason that Perl could not run as fast as C
.... it's just that no one has cared to implement it.

C code will never run as fast as assembler langs.

For a large function with many variables and/or subcalls, a good C
compiler will almost always beat an assembler programmer by sheer
brute force - no matter how good the programmer is. I suspect the
same is true for most HLLs that have good optimizing compilers.

I've spent years doing hard real time programming and I am an expert
in C and a number of assembly languages. It is (and has been for a
long time) impractical to try to beat a good C compiler for a popular
chip by writing from scratch in assembly. It's not just that it takes
too long ... it's that most chips are simply too complex for a
programmer to keep all the instruction interaction details straight in
his/her head. Obviously results vary by programmer, but once a
function grows beyond 100 or so instructions, the compiler starts to
win consistently. By the time you've got 500 instructions (just a
medium sized C function) it's virtually impossible to beat the
compiler.

In functional languages where individual functions tend to be much
smaller, you'll still find very complex functions in the disassembly
that arose from composition, aggressive inlining, generic
specialization, inlined pattern matching, etc. Here an assembly
programmer can quite often match the compiler for a particular
function (because it is short), but overall will fail to match the
compiler in composition.

When maximum speed is necessary it's almost always best to start with
an HLL and then hand optimize your optimizing compiler's output.
Humans are quite often able to find additional optimizations in
assembly code that they could not have written as well overall in the
first place.

George
 
X

Xah Lee

Dear George Neuner,


George said:
This depends on whether someone has taken the time to create a high
quality optimizing compiler.

try to read the sentence. I quote:
«The phenomenon of creating code that are inefficient is proportional
to the highlevelness or power of the lang. In general, the higher
level of the lang, the less possible it is actually to produce a code
that is as efficient as a lower level lang.»

According to what "power" estimation? Assembly, C/C++, C#, Pascal,
Java, Python, Ruby and Lisp are all Turing Complete. I don't know
offhand whether Mathematica is also TC, but if it is then it is at
most equally powerful.

it's amazing that every tech geekers (aka idiots) want to quote
“Turing Complete†in every chance. Even a simple cellular automata,
such as Conway's game of life or rule 110, are complete.

http://en.wikipedia.org/wiki/Conway's_Game_of_Life
http://en.wikipedia.org/wiki/Rule_110

in fact, according to Stephen Wolfram's controversial thesis by the
name of “Principle of computational equivalenceâ€, every goddamn thing
in nature is just about turing complete. (just imagine, when you take
a piss, the stream of yellow fluid is actually doing turning complete
computations!)

for a change, it'd be far more interesting and effective knowledge
showoff to cite langs that are not so-called **** of the turing
complete.

the rest of you message went on stupidly on the turing complete point
of view on language's power, mixed with lisp fanaticism, and personal
gribes about merits and applicability assembly vs higher level langs.
It's fine to go on with your gribes, but be careful in using me as a
stepping stone.

Xah
∑ http://xahlee.org/

☄
 
T

Terry Reedy

Jon said:
For the interested, with MMA 6, on a Pentium 4 3.8Ghz:

The code that Jon posted:

Timing[Export["image-jon.pgm", Graphics@Raster@Main[2, 100, 4]]]
{80.565, "image-jon.pgm"}

That is not the code I posted: you are using Xah's parameters that generate
a different (and largely empty) scene.
The code that Xah posted:

Timing[Export["image-xah.pgm", Graphics@Raster@Main[2, 100, 4.]]]
{42.3186, "image-xah.pgm"}

So Xah's code is about twice as fast as Jon's code, on my computer.

The resulting files were identical (and both looked like pure white
images; I thought they'd be interesting!).

Use 9, 512, 4 instead of 2, 100, 4 and you will get a more interesting image
of over 80,000 spheres with shadows and diffuse lighting.

This is a really important difference: half of that program is dedicated to
hierarchical spherical bounding volumes that are essential when tracing a
large number of spheres. Xah solved a completely different problem by
simplifying the scene to only 5 spheres, where bounding volumes are useless
and the performance characteristics of the program are wildly different.

Lest anyone doubt that problem size is important for comparing program
run times, consider the following realistic example: the run time of
algorithm A is n*n, that of B is 10.6666666667*n*log2(n). A is faster
for small problems, B for large problems, with the crossover at 64. A
hybrid algorithm C could use B for large problems and A for small
problems and small subproblems generated by B's divide and conquer
technique. Python's list.sort is such a hybrid of binary insertion sort
and merge sort, with a crossover at 64 based on experimental data.

tjr
 
W

Wesley MacIntosh

A said:
A moron, wrote: [snip]

my machine (PPC Mac, OSX 10.4.x).

Well, that explains a great deal.

Actually, I suspect all these newsgroups are being trolled.
 
K

Kaz Kylheku

So, pay me $300 as consulting fee. If the result does not comply to
the above spec, money back guaranteed.

*LOL*

Did you just offer someone the exciting wager of ``your money back or nothing?

No matter what probability we assign to the outcomes, the /upper bound/
on the expected income from the bet is at most zero dollars. Now that's not so
bad. Casino games and lotteries have that property too; the net gain is
negative.

But your game has no variability to suck someone in; the /maximum/ income from
any trial is that you break even, which is considered winning.

If you ever decide to open a casino, I suggest you stop playing with
Mathematica for a while, and spend a little more time with Statistica,
Probabilica, and especially Street-Smartica.

:)
 
X

Xah Lee

you didn't give me a challenge.

Thomas gave you the challenge:

"What I want in return is you to execute and time Dr. Harrop's original
code, posting the results to this thread... By Dr. Harrop's original code,
I specifically mean the code he posted to this thread. I've pasted it below
for clarity.".

Thomas even quoted my code verbatim to make his requirements totally
unambiguous. Note the parameters [9, 512, 4] in the last line that he and I
both gave:

AbsoluteTiming[Export["image.pgm", Graphics@Raster@Main[9, 512, 4]]]

You have not posted timings of that, let alone optimized it. So you failed.

The first parameter to your Main specifies some kinda recursively
stacked spheres in the rendered image. The second parameter is the
width and height of the pixels in the rendered image.

I tried to run them but my computer went 100% cpu and after i recall 5
min its still going. So, i reduced your input. In the end, with
reduced input, it shows my code is 5 times faster (running Mathematica
v4 on OS X 10.4.x with PPC 1.9 GHz), and on the other guy's computer
with Mathematica 6 he says it's twice as fast.

Given your code's nature, it is reasonably to assume that with your
original input my code would still be faster than yours. You claim it
is not or that it is perhaps just slightly faster?

It is possible you are right. I don't want to spend the energy to run
your code and my code and possible hog my computer for hours or
perhaps days. As i said, your recursive Intersect is very badly
written Mathematica code. It might even start memory swapping.

Also, all you did is talking bullshit. Thomas actually is the one took
my challenge to you and gave me $20 to prove my argument to YOU. His
requirement, after the payment, is actually, i quote:

«Alright, I've sent $20. The only reason I would request a refund is
if you don't do anything. As long as you improve the code as you've
described and post the results, I'll be satisfied. If the improvements
you've described don't result in better performance, that's OK.»

He haven't posted since nor emailed me. It is reasonable to assume he
is satisfied as far as his payment to me to see my code goes.

You, kept on babbling. Now you say that the input is different. Fine.
How long does that input actually take on your computer? If days, i'm
sorry i cannot run your toy code on my computer for days. If in few
hours, i can then run the code overnight, and if necessary, give you
another version that will be faster with your given input to shut you
the **** up.

However, there's cost to me. What do i get to do your homework? It is
possible, that if i spend the energy and time to do this, then you
again refuse to acknowledge it, or kept on complaining about something
else.

You see, newsgroup is the bedrock of bullshit. You bullshit, he
bullshits, everybody brags and bullshit because there is no stake. I
want sincerity and responsibility backed up, with for example paypal
deposits. You kept on bullshitting, Thomas gave me $20 and i produced
a code that reasonably demonstrated at least how unprofessional your
Mathematica code was.

Here's the deal. Pay me $20, then i'll creat a version of Mathematica
code that has the same input as yours. Your input is Main[9, 512, 4],
as i have exposed, your use of interger in the last part for numerical
computation is Mathematica incompetence. You didn't acknowledge even
this. I'll give a version of Mathematica with input Main[9, 512, 4.]
that will run faster than yours. If not, money back guaranteed. Also,
pay me $300, then i can produce a Mathematica version no more than 10
times slower than your OCaml code, this should be a 70000 times
improvement according to you. Again, money back guarantee.

If i don't receive $20 or $300, this will be my last post to you in
this thread. You are just a bullshitter.

O wait... my code with Main[9, 512, 4.] and other numerical changes
already makes your program run faster regardless of the input size.
What a motherfucking bullshit you are. Scratch the $20. The $300
challenge still stands firm.

Xah
∑ http://xahlee.org/

☄
 
X

Xah Lee

you didn't give me a challenge.

Thomas gave you the challenge:

"What I want in return is you to execute and time Dr. Harrop's original
code, posting the results to this thread... By Dr. Harrop's original code,
I specifically mean the code he posted to this thread. I've pasted it below
for clarity.".

Thomas even quoted my code verbatim to make his requirements totally
unambiguous. Note the parameters [9, 512, 4] in the last line that he and I
both gave:

AbsoluteTiming[Export["image.pgm", Graphics@Raster@Main[9, 512, 4]]]

You have not posted timings of that, let alone optimized it. So you failed.

The first parameter to your Main specifies some kinda recursively
stacked spheres in the rendered image. The second parameter is the
width and height of the pixels in the rendered image.

I tried to run them but my computer went 100% cpu and after i recall 5
min its still going. So, i reduced your input. In the end, with
reduced input, it shows my code is 5 times faster (running Mathematica
v4 on OS X 10.4.x with PPC 1.9 GHz), and on the other guy's computer
with Mathematica 6 he says it's twice as fast.

Given your code's nature, it is reasonably to assume that with your
original input my code would still be faster than yours. You claim it
is not or that it is perhaps just slightly faster?

It is possible you are right. I don't want to spend the energy to run
your code and my code and possible hog my computer for hours or
perhaps days. As i said, your recursive Intersect is very badly
written Mathematica code. It might even start memory swapping.

Also, all you did is talking bullshit. Thomas actually is the one took
my challenge to you and gave me $20 to prove my argument to YOU. His
requirement, after the payment, is actually, i quote:

«Alright, I've sent $20. The only reason I would request a refund is
if you don't do anything. As long as you improve the code as you've
described and post the results, I'll be satisfied. If the improvements
you've described don't result in better performance, that's OK.»

He haven't posted since nor emailed me. It is reasonable to assume he
is satisfied as far as his payment to me to see my code goes.

You, kept on babbling. Now you say that the input is different. Fine.
How long does that input actually take on your computer? If days, i'm
sorry i cannot run your toy code on my computer for days. If in few
hours, i can then run the code overnight, and if necessary, give you
another version that will be faster with your given input to shut you
the **** up.

However, there's cost to me. What do i get to do your homework? It is
possible, that if i spend the energy and time to do this, then you
again refuse to acknowledge it, or kept on complaining about something
else.

You see, newsgroup is the bedrock of bullshit. You bullshit, he
bullshits, everybody brags and bullshit because there is no stake. I
want sincerity and responsibility backed up, with for example paypal
deposits. You kept on bullshitting, Thomas gave me $20 and i produced
a code that reasonably demonstrated at least how unprofessional your
Mathematica code was.

Here's the deal. Pay me $20, then i'll creat a version of Mathematica
code that has the same input as yours. Your input is Main[9, 512, 4],
as i have exposed, your use of interger in the last part for numerical
computation is Mathematica incompetence. You didn't acknowledge even
this. I'll give a version of Mathematica with input Main[9, 512, 4.]
that will run faster than yours. If not, money back guaranteed. Also,
pay me $300, then i can produce a Mathematica version no more than 10
times slower than your OCaml code, this should be a 70000 times
improvement according to you. Again, money back guarantee.

If i don't receive $20 or $300, this will be my last post to you in
this thread. You are just a bullshitter.

O wait... my code with Main[9, 512, 4.] and other numerical changes
already makes your program run faster regardless of the input size.
What a motherfucking bullshit you are. Scratch the $20. The $300
challenge still stands firm.

Xah
∑ http://xahlee.org/

☄
 
X

Xah Lee

Lest anyone doubt that problem size is important for comparing program
run times, consider ...

just in case there's any doubt:

Simply change these lines in Jon's program:

Main[9, 512, 4] to Main[9, 512, 4.]

and it will run faster.

Also, change this line:

Block[{scene = Create[level, {0, -1, 4}, 1]},

to

Block[{scene = Create[level, {0., -1., 4.}, 1.]},

will make it faster further. (both of which are in my version. The
“Block†can be replaced with “Withâ€.)

As i said, this error in a Mathematica code in the context of speed is
a major blunder. His denial makes him a stubborn moron.

Reference:

• A Mathematica Optimization Problem
http://xahlee.org/UnixResource_dir/writ/Mathematica_optimization.html

Xah
∑ http://xahlee.org/

☄
 
X

Xah Lee

Note that this program takes several days to compute in Mathematica (even
though it takes under four seconds in other languages) so don't expect to
see a genuinely optimized version any time soon... ;-)

Note that Jon's Mathematica code is of very poor quality, as i've
given detailed analysis here:

• A Mathematica Optimization Problem
http://xahlee.org/UnixResource_dir/writ/Mathematica_optimization.html

I'm not sure he's intentionally making Mathematica look bad or just
sloppiness. I presume it is sloppiness, since the Mathematica code is
not shown in his public website on this speed comparison issue. (as
far as i know) I suppose, he initialled tried this draft version, saw
that it is too slow for comparsion, and probably among other reason he
didn't include it in the speed comparison. However, in this thread
about Mathematica 7, he wanted to insert his random gribe to pave
roads to post his website books and url on OCml/f#, so he took out
this piece of Mathematica to bad mouth it and bait. He ignored my
paypal challenge, but it so happens that someone else paid me $20 to
show a better code, and in the showdown, Jon went defensive that just
make him looking like a major idiot.

Xah
∑ http://xahlee.org/

☄
 
A

alex23

I'm not sure he's intentionally making Mathematica look bad or just
sloppiness.

Actually, there's only one person here tainting Mathematica by
association, and it's not Jon.
 
S

sln

Note that Jon's Mathematica code is of very poor quality, as i've
given detailed analysis here:

• A Mathematica Optimization Problem
http://xahlee.org/UnixResource_dir/writ/Mathematica_optimization.html

I'm not sure he's intentionally making Mathematica look bad or just
sloppiness. I presume it is sloppiness, since the Mathematica code is
not shown in his public website on this speed comparison issue. (as
far as i know) I suppose, he initialled tried this draft version, saw
that it is too slow for comparsion, and probably among other reason he
didn't include it in the speed comparison. However, in this thread
about Mathematica 7, he wanted to insert his random gribe to pave
roads to post his website books and url on OCml/f#, so he took out
this piece of Mathematica to bad mouth it and bait. He ignored my
paypal challenge, but it so happens that someone else paid me $20 to
show a better code, and in the showdown, Jon went defensive that just
make him looking like a major idiot.

Xah
? http://xahlee.org/

?
Ad hominem
 
S

sln

Xah said:
A moron, wrote:
You failed the challenge that you were given.
you didn't give me a challenge.

Thomas gave you the challenge:

"What I want in return is you to execute and time Dr. Harrop's original
code, posting the results to this thread... By Dr. Harrop's original code,
I specifically mean the code he posted to this thread. I've pasted it below
for clarity.".

Thomas even quoted my code verbatim to make his requirements totally
unambiguous. Note the parameters [9, 512, 4] in the last line that he and I
both gave:

AbsoluteTiming[Export["image.pgm", Graphics@Raster@Main[9, 512, 4]]]

You have not posted timings of that, let alone optimized it. So you failed.

The first parameter to your Main specifies some kinda recursively
stacked spheres in the rendered image. The second parameter is the
width and height of the pixels in the rendered image.

I tried to run them but my computer went 100% cpu and after i recall 5
min its still going. So, i reduced your input. In the end, with
reduced input, it shows my code is 5 times faster (running Mathematica
v4 on OS X 10.4.x with PPC 1.9 GHz), and on the other guy's computer
with Mathematica 6 he says it's twice as fast.

Given your code's nature, it is reasonably to assume that with your
original input my code would still be faster than yours. You claim it
is not or that it is perhaps just slightly faster?

It is possible you are right. I don't want to spend the energy to run
your code and my code and possible hog my computer for hours or
perhaps days. As i said, your recursive Intersect is very badly
written Mathematica code. It might even start memory swapping.

Also, all you did is talking bullshit. Thomas actually is the one took
my challenge to you and gave me $20 to prove my argument to YOU. His
requirement, after the payment, is actually, i quote:

«Alright, I've sent $20. The only reason I would request a refund is
if you don't do anything. As long as you improve the code as you've
described and post the results, I'll be satisfied. If the improvements
you've described don't result in better performance, that's OK.»

He haven't posted since nor emailed me. It is reasonable to assume he
is satisfied as far as his payment to me to see my code goes.

You, kept on babbling. Now you say that the input is different. Fine.
How long does that input actually take on your computer? If days, i'm
sorry i cannot run your toy code on my computer for days. If in few
hours, i can then run the code overnight, and if necessary, give you
another version that will be faster with your given input to shut you
the **** up.

However, there's cost to me. What do i get to do your homework? It is
possible, that if i spend the energy and time to do this, then you
again refuse to acknowledge it, or kept on complaining about something
else.

You see, newsgroup is the bedrock of bullshit. You bullshit, he
bullshits, everybody brags and bullshit because there is no stake. I
want sincerity and responsibility backed up, with for example paypal
deposits. You kept on bullshitting, Thomas gave me $20 and i produced
a code that reasonably demonstrated at least how unprofessional your
Mathematica code was.

Here's the deal. Pay me $20, then i'll creat a version of Mathematica
code that has the same input as yours. Your input is Main[9, 512, 4],
as i have exposed, your use of interger in the last part for numerical
computation is Mathematica incompetence. You didn't acknowledge even
this. I'll give a version of Mathematica with input Main[9, 512, 4.]
that will run faster than yours. If not, money back guaranteed. Also,
pay me $300, then i can produce a Mathematica version no more than 10
times slower than your OCaml code, this should be a 70000 times
improvement according to you. Again, money back guarantee.

If i don't receive $20 or $300, this will be my last post to you in
this thread. You are just a bullshitter.

O wait... my code with Main[9, 512, 4.] and other numerical changes
already makes your program run faster regardless of the input size.
What a motherfucking bullshit you are. Scratch the $20. The $300
challenge still stands firm.

Xah
? http://xahlee.org/

?
Ad hominem
 
X

Xah Lee

Jon said:
Only for trivial input and not for the challenge you were given.

what challenge?
That code is evaluated once to build the scene. There is no point in
optimizing it.

The point is optimizing your incompetence.
That performance issue only affects trivial problems and, in particular,
does not affect the problem you were trying to solve.

solve your mom?

Xah
∑ http://xahlee.org/

☄
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,143
Latest member
DewittMill
Top