Is Scheme Faster than C?
cs.indiana.edu
cs.indiana.edu
No Scheme compiler would be likely to do those transformations for you.
...A runtime profile of my program revealed that the majority of time was spent in the C routines "malloc" and "free."
For all of the beginning programmers and most of the student programmers out there: Yes often a fast JIT VM might actually beat your C or get pretty close! If you ever become a good programmer, then you can do much better than the JIT in key situations.
EDIT: There's a self evaluation method here for aspiring C programmers. Start benchmarking your code against the same thing in LuaJIT. You're not "good" until you know how to routinely beat it by a factor approaching 2. And that's necessary, but not sufficient.
EDIT: Added "involving memory management"
EDIT: To students doing C programming: Be honest, now, but have you ever checked?
From the author Jerey Mark Siskind's research statement:
It uses the results of flow analysis to perform life-time analysis,
escape analysis, points-to analysis, and must-alias analysis. ...
It also uses the above analysis to support flow-directed region-based
storage management, where run-time garbage collection is replaced
with static allocation and deallocation on a per-abstract-value
and per-program-point basis. It also performs flow-directed
lightweight CPS conversion,.. to support extremely efficient first-class continuations.
It is quite remarkable that even without any type annotations Stalin can hold its own against a hand written C and often beat it as well.http://en.wikipedia.org/wiki/Stalin_(Scheme_implementation)
(Has escaped chrismonsantoization)
Is "Stalin can hold its own against a hand written C and often beat it" just your paraphrase of wikipedia's quote from a bare assertion in Jeffrey Siskind's Purdue research statement - or due you have some numbers to share?
Numbers circa 2008: take a look at section 6 in ftp://ftp.ecn.purdue.edu/qobi/TR-ECE-08-02.pdf and ftp://ftp.ecn.purdue.edu/qobi/TR-ECE-08-03.pdf These are numbers from StalinGrad. A automatic differentiation engine written in Stalin (hence the Grad).
Also the thread http://groups.google.com/group/comp.lang.lisp/browse_frm/thr... that got me interested in Stalin in the first place.
With all that said, any reason to distrust research statements ? Those are usually taken seriously in academia. One only jeopardizes his position by bluffing.
This is not specific to Scheme, though - while it's a good prototyping language, so are Lua (my favorite, and LuaJIT reduces the need for C), awk, Python, etc.
Knowing how to implement the prototyping languages' constructs efficiently in the "fast" language is important, though.
Of course, "fast" and "convenient" can also be the same language, such as prototyping in Common Lisp and then adding declarations. OCaml is also quite good.
This is where Scheme really won. Because of its extremely algorithmic---almost mathematical---nature, Scheme can be easily manipulated in a sort of algebraic style.
> Real efficiency comes from elegant solutions, not optimized programs. Optimization is always just a few correctness-preserving transformations away
Trying to do both at the same time is usually slower, in the long run.
On the other hand, the original quote seems to regard elegance and optimization as opposed. (And really gloss over the step of porting your elegant routines by hand to C!)
Fixed that title for you.
But I'd be interested in how the port to C actually happened. That is, if he translated the functional aspects of the algorithm, or if he just copied intermediary C code that a Scheme compiler can generate.
We were taught to translate a recursive program to continuation passing style in a way that many variables could be translated to registers directly. If I remember correctly, Jonathan translated this from Scheme to C and just compiled that result.
I guess if you only write number crunching code, then yeah. But if you write an app (web or client) - what good is Lisp?
http://en.wikipedia.org/wiki/Common_Lisp_Object_System
There is also Arc, the language Paul Graham and Robert Morris wrote for the web. This site is written it it.
See http://en.wikipedia.org/wiki/Closure_(computer_programming)
Chastised, Anton took his leave from his master and returned to his cell, intent on studying closures. He carefully read the entire "Lambda: The Ultimate..." series of papers and its cousins, and implemented a small Scheme interpreter with a closure-based object system. He learned much, and looked forward to informing his master of his progress.
On his next walk with Qc Na, Anton attempted to impress his master by saying "Master, I have diligently studied the matter, and now understand that objects are truly a poor man's closures." Qc Na responded by hitting Anton with his stick, saying "When will you learn? Closures are a poor man's object." At that moment, Anton became enlightened.
Personally, I see closures as objects that the compiler cooks up on your behalf. This coming from a compiler background, where said compiler is usually implemented in C++ :P.
[1] http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/m...
Scripting languages are faster to code in.
Fortran is faster at complex matrix maths.
Lisp is faster to code in and faster to run for a large set of computing problems.
C wins the trade-of of speed-to-create vs speed-of-execution for most system programming tasks but usually when compared to bare assembly code. But there are a large number of problems that it is horribly unsuited for. Hence we end up with c-programs with accidentally embedded lisp implementations.
* - where faster can also mean faster to code to a secure standard.
See Greenspun's Tenth Rule: Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.
And of course the famous corollary: Including Common Lisp.
The more I hear about the Lisp family of languages, the more I want to give them a try sometime...
The lesson learned is a good one though: Good design always wins. In real life, that's obvious almost immediately, yet the concept seems to elude the vast majority of programmers.
In reality the difficulty in programming is creating powerful, flexible designs. If you can look at your own code a year later and say "wow - this is good" - then you win.
> ... optimizing a trivial algorithm is not
> something you'll encounter out of school.
Sometimes it is. For me, it happens a few times a year.More importantly, the techniques, methods and mind set are critical daily in the code I and my employees write.
But we aren't doing web development.
There's also another thing that happens, which is to look at a big mess of twisty code and think about it, finally seeing that it should have been done as a simple algorithm. Then you get to delete a lot of code and replace it with a small bit of clear code.
There are many more ways the simple things learned in school help in the real world.
DSP transformations are represented in a Scheme-like language. The optimizer performs operations on this language then compiles to C code.
I worked on the Spiral project on things tangental to the DSP generator, but wrote my own optimizing DSP compiler based on Spiral technology for class in university.
My daily work for the last few weeks has been optimizing speedwise our pipeline.
Usually what we do is OpenMP (openmp.org) the code where it's possible (we deal with lots of DXT compression, mipmaps, normal map calucations, etc.)
Then where possible decrease the floating point accuracy to point where it's acceptable, and use SSE2 through some veclib.
It's all in C (C++) and the difference can be 1:10 and even more.
All I'm saying is this - you sit down, find your bottleneck and do something about it. But simply saying this is faster than this is pointless.
That to be said the language shootout is how it should be done - you have people using (trying at least) to use the same algorithms in different languages by allowing certain language (implementation) optimizations, or available libs.
Yes, I've seen LuaJIT, and LispWorks (which I love dearly) producing better code than C++, especially when comes to std::string put in stdext::hash_map<> simply because it's just harder to intern stuff in C++ (unless you do it manually). In Lua every string is interned, and in LispWorks (and in Common Lisp in general) as long as it's symbol it can be interned.
Guess it's become part of IU lore :-)
Friedman is at Indiana, so the similarity in the transformation is no surprise. I'm surprised the arty doesn't mention Friedman.
Can anyone explain this with an example? I have been pondering what he meant with this for a long time.
Can anyone explain this with an example? I have been pondering what he meant with this for a long time. "
see the cps-transform rewrite rules in "Essentials of Programming Languages". The first edition has the densest and most extensive explanation. The third edition has the clearest, but a relatively attenuated exposition.