* Scott Schwartz | Just to be fair, you ought to measure the same thing. In the first | case you measure the time to load and initialize the C runtime system. | In the second case you already have Lisp fired up, so you omit the | measurements for the cost of doing that. Let's see the time for the | a.out generated by ACL or CMUCL, starting at the shell prompt.
right. the usual reaction from "C just _has_ to win"-people is to force everything to fit its paradigm. when C loses by a factor of 2, it has to be explained away with some nonsense like the above.
a Lisp system is like a shell. in Unix, the shell evaluates your command line, including forking and running programs and whatnot. in Lisp systems, Lisp evaluates your expressions. if you goal in life is to get something done efficiently, you measure what is natural in each environment. if your goal in life is to execute a.out files efficiently, never mind what they do, then, and only then, should you generate a.out files for all test cases.
but let's see what difference the runtime system _does_ make. ACL has a nice foreign function interface that should even out the costs:
user(40): (time (lotto 35 7)) ; cpu time (non-gc) 4,567 msec user, 0 msec system ; cpu time (gc) 0 msec user, 0 msec system ; cpu time (total) 4,567 msec user, 0 msec system ; real time 4,591 msec ; space allocation: ; 2 cons cells, 0 symbols, 32 other bytes 6724520 user(41): (time (c-lotto 35 7)) ; cpu time (non-gc) 4,417 msec user, 0 msec system ; cpu time (gc) 0 msec user, 0 msec system ; cpu time (total) 4,417 msec user, 0 msec system ; real time 4,431 msec ; space allocation: ; 4 cons cells, 0 symbols, 32 other bytes 6724520
(these are stabilized values, i.e., time repeated the same values several times in a row.)
we recall that the C function in the fork-and-execute version used 4.42 seconds of user time. in other words, the difference is negligible.
note: the foreign function interface to CMUCL is less well documented, and I have never used it much. however, I'm using Allegro CL for a project that uses lots of binary protocols for which we already have working code.
#\Erik -- 1,3,7-trimethylxanthine -- a basic ingredient in quality software.
| a Lisp system is like a shell. in Unix, the shell evaluates your command | line, including forking and running programs and whatnot. in Lisp systems, | Lisp evaluates your expressions. if you goal in life is to get something | done efficiently, you measure what is natural in each environment. if your | goal in life is to execute a.out files efficiently, never mind what they | do, then, and only then, should you generate a.out files for all test | cases.
Yes, my goal in life is to execute a.out files efficiently, because that's the way my OS of choice does things. If Lisp doesn't easily accomodate itself to that environment, it might be part of the reason why Lisp is unpopular.
| but let's see what difference the runtime system _does_ make. ACL has a | nice foreign function interface that should even out the costs:
I don't think it does even out the costs. For one thing, you didn't measure the cost of (load "lotto.o").
| you're being stupid on purpose. you don't include compilation, assembling, | and linking time in C programs, so why do you do it for Lisp? go away.
That's uncalled for. My point is valid: you want to treat lisp like a shell, but then ignore the cost of doing so when the overhead is in question. In contrast, the time you gave for the a.out version includes the cost of dynamically loading all the shared libraries.
In article <5c7os1$...@news-rocq.inria.fr> har...@pauillac.inria.fr "Robert Harley" writes:
> There are times when ultra-safe, high-level prototyping is productive > and there are times when non-portable hackery in machine code is > essential. But most of the time, most programmers strike a balance > between these two extremes and find that C is a happy medium.
Actually, there are ways of turning off checking in Lisp. Common Lisp allows the programmer to write a declaration telling the compiler to maximise speed, and minimize safety, amoung other things. The scope can be global or local, depending on how the declaration is made.
Safty and speed are _not_ mutually exclusive. The choice doesn't have to made globally. Some languages give you a choice, but your first choice is the language to use. After that...
> Horses for courses and all that.
I have to agree with Erik on this. C doesn't give you the choice that CL does. What actually CL compilers do with the optimise declaration is another matter, of course.
Tim Pierce <twpierce+use...@mail.bsd.uchicago.edu> writes: > Maybe I'm getting a bit off the point. The real problem doesn't > strike me as one of ignorant programmers not *knowing* that > overflow can occur (although in practice that is a legitimate > concern). The problem is that the programmer needs to worry about > it at all, and that the language itself does not provide for a > convenient facility for dealing with such error conditions.
> In some contexts that's undoubtedly a feature, but not in the > context of writing mission-critical user-level applications. > Forcing the programmer to make a manual check for overflow every > time a calculation is made makes for wasteful and inefficient > development.
I'm not sure that I agree.
Users are probably happier getting "Integer overflow: program aborted" in mission-critical applications than silently getting incorrect results. But not a *lot* happier, I'd bet.
The vast majority of integer calculations made in programs simply *can't* overflow, unless some grave logic error has been made that will prevent the program working at all. Programmers well know when they're writing a line of code of which the size of the result is sufficiently unknown that it might overflow. They need to *think* about whether it can overflow or not, and what to do about it if it does. Automatic checks for overflow might be useful as an ambulance at the bottom of the cliff, but any programmer who allows the automatic overflow machinery to kick in on a machine integer calculation in a mission-critical application has badly failed in his duties.
"Never test for any error that you don't know how to handle"
-- Bruce
-- ...in 1996, software marketers wore out a record 31,296 copies of Roget's Thesaurus searching for synonyms to the word "coffee" ...
* D. J. Bernstein | Expand the tail recursion in C, like this--- : | ---and you get a 5x speedup. That's more than twice as fast as your | proud example of fast LISP code.
just to be entirely clear on this, the code in the "proud example" was posted by a fool who posted both the C and the Lisp code to debunk Lisp's speed. he was indeed very proud of his code, and he made no attempt to speed up the C code once he was shown that CMUCL outdid it with a factor of 2. you're not answering the question as asked if you change the premises they way you have done. but to show his state of mind, let me include a sentence from his message (translated):
Execution time under CLISP on my old Pentium/Linux: 140 seconds. After compiling the stuff, however, I got it down to 11 seconds.
he was comparing _interpreted_ code to his compiled C code! you can judge his brilliance from this alone. his refusal to acknowledge that CLISP ran byte-code was the reason I wanted to beat up his example.
however, your challenge was much tougher.
| Of course, it's bad to use the stack for temporary space. Allocate what | you need at the beginning, handling out-of-memory explicitly rather than | crashing, and use some obvious dynamic programming--- : | ---for another 500x speedup. How would you translate that to LISP? How | fast is the result?
since both the Lisp and the C versions are very fast, I ran a million passes over each version to get accurate timing. (SunOS 4 has some odd notions of internal clock speed, measuring in 100Hz and reporting i 60Hz, thereby losing a lot of precision.) your C code used 78 s, but allocated 36M of memory and needed 7 s of system time to do so. a call to free(u) and a slight rewrite of the value-returning form increased the time to 82 s, but reduced the system time to less than .3 seconds. using `alloca' to allocate on the stack, instead, it's down to 66 s. the Lisp version uses 104 s, plus 1.1 s of garbage collection and .3 s of system time. it had consed a total of 48M. (experiments showed that zeroing a pre-allocated vector was _much_ slower than allocating fresh memory.)
here's the code I used for the comparisons:
/* binomial.c -*- mode: c -*- 35453.668341 */
int binomial(int n, int k) { int i, j, *u; if (k > n) return 0; i = n - k; if (k > i) k = i; if (!k) return 1; u = (int *) alloca((k + 1) * sizeof (int)); if (!u) return -1; u[0] = 1; for (i = 1; i <= n; ++i) for (j = k; j > 0; --j) u[j] += u[j - 1]; return u[k];
(defun binomial (n k) (declare (fixnum n k)) (locally (declare (optimize (speed 3) (safety 0) (debug 0))) (unless (and (plusp k) (plusp n)) (error "No possible result")) (when (> k n) (cerror "Evaluate (binomial ~*~D ~0@*~D) instead" "Reversed arguments in (binomial ~D ~D)?" n k) (rotatef n k)) (setq k (min k (- n k))) (when (zerop k) (return-from binomial 1)) (let* ((j 0) (u (make-array (1+ k) :initial-element 0))) (declare (fixnum j) (type (vector fixnum) u)) (setf (svref u 0) 1) (tagbody outer (setq j k) inner (incf (svref u j) (svref u (1- j))) (unless (zerop (decf j)) (go inner)) (unless (zerop (decf n)) (go outer))) (svref u k))))
#| binomial.cl ends |#
there may be ways to improve this further; I don't have time to sit down and _really_ tune this code (the above was based on a couple hunches and a little experimentation, and took me about 40 minutes to tweak this into place, plus about half an hour CPU time for tests running so long at a time I could get some real work done in between.) clearly, this is an immense improvement over the previous code, a factor of 43,100! (I have been told that this is because the SPARC CPU (or my version of it) handles recursion badly due to limited register windows. I'm seeking more information on this.)
#\Erik -- 1,3,7-trimethylxanthine -- a basic ingredient in quality software.
* Scott Schwartz | My point is valid: you want to treat lisp like a shell, but then ignore | the cost of doing so when the overhead is in question. In contrast, the | time you gave for the a.out version includes the cost of dynamically | loading all the shared libraries.
your "point" is not only invalid, it is completely ridiculous.
I measured 1 million calls to these functions, and got the timings I did, and don't even try to believe I fork'ed and exec'ed a million times. I wanted to measure the time of the function itself, not the time of running a program. by running the same function a million times inside a given process, the time information I get for Lisp can be expressed as
1000000(binomial+looper)
and for the C as
1000000(binomial+looper)+startup
to find the time of the looper and the startup costs, I ran both with (binomial 35 35) to find the cost of the function call. those timings were subtracted from the times I listed.
considering the amount of idiocy I get from C users when timing stuff and C loses or proves to be less than the super-efficient hands-down winner of all contests, my belief that C damages people's brains in irreparable ways is indeed solidifying.
#\Erik -- 1,3,7-trimethylxanthine -- a basic ingredient in quality software.
d...@koobera.math.uic.edu (D. J. Bernstein) wrote:
>David H. Thornley <thorn...@cs.umn.edu> wrote: >> this works as a statement, not as an embedded expression, > [ ... ] >> the macro can evaluate u twice,
>Apparently you're unaware that C programmers use lowercase for macros >that simulate functions, uppercase for macros that don't.
That's fascinating, because many C programmers fall into exactly the trap he mentioned with writing MIN() or MAX() macros. Maybe they forgot?
Robert Rodgers <rsrod...@wam.umd.edu> wrote: > That's fascinating, because many C programmers fall into exactly the > trap he mentioned with writing MIN() or MAX() macros.
The convention is that you can write
#define MAX(a,b) ((a) < (b) ? (b) : (a))
because MAX, being uppercase, doesn't have to simulate a function. If someone writes
c = MAX(a++,b);
then he's making the mistake. If, on the other hand, you had written
#define max(a,b) ((a) < (b) ? (b) : (a))
then callers would be entirely justified in writing
c = max(a++,b);
and it'd be your fault that the code doesn't work.
On Fri, Jan 24, 1997 10:11 PM, Rainer Joswig <mailto:jos...@lavielle.com> wrote:
>You may want to upgrade your SPARCstation to a Macintosh PowerBook >5300c >with Macintosh Common Lisp 4.0
>? (time (lotto 35 7)) >(LOTTO 35 7) took 1,183 milliseconds (1.183 seconds) to run. >Of that, 17 milliseconds (0.017 seconds) were spent in The >Cooperative >Multitasking Experience. >6724520
Likewise, the times on a PowerMac 7200/75:
? (time (lotto 35 7)) (LOTTO 35 7) took 1,793 milliseconds (1.793 seconds) to run. Of that, 40 milliseconds (0.040 seconds) were spent in The Cooperative Multitasking Experience. 6724520
It's worth pointing out that the "cooperative multitasking experience" is is the time spent by the Mac OS to give cycles to other applications which don't have the user's focus. I found that the total time tracked very closely with this OS overhead; thus the total CPU time in the above example is 1.753 seconds.
--------------------------------------------------------- David B. Lamkins --- http://www.teleport.com/~dlamkins/ CPU Cycles: Use them now, or lose them forever... ---------------------------------------------------------
> This is one of these macros, where u (whatever expression it is) > may be evaluated twice. Which may go wrong. For example if > this is not an atomic instruction.
C IMHO has either too few internal types or it doesn't allow to add types easy enough. It's a 90% language: it fits 90% of the needs of 90% of the users well enough. There are enough lanuages out there that either have all the internal types you want to (Ada), that allow to add them in case (C++, Ada), or don't have the problem with this concept at all (e.g. Forth - + is just a function on two cells, add check+, another function on two cells on the stack, something like : check+ ( u v -- r ) over + tuck u< abort" overflow" ; ).
Overall, I as programmer want the control what happens in case of an overflow. I often really use mod 2^32 values, and I know how to do it (e.g. you compare with (a-b)<0). I would go mad with a programming language that thinks it must abort or jump to the error handler. The variable names of C certainly are missleading, they are signed and unsigned "cell", not "int".
Languages are tools. Nothing more. Choose your tool as appropriate for the case. If you find none, choose a language that is appropriate to create new tools. These languages are rarely mainstream, as rarely, as hammer and chimney are viewed as convenient tools (except perhaps for making horse shoes). So they are niche languages. Forth is used in embedded control, Lisp in AI. Neither needs a lot of man power behind it, especially, since these tools make the programmers that know how to use them very productive.
In article <E4IAvn....@hplb.hpl.hp.com>, <t...@hplb.hpl.hp.com> wrote: >John Bayko (ba...@borealis.cs.uregina.ca) wrote: >| Theory #51 of "Why C became the most popular language": C was the >|first language where I/O was *not* part of the language.
>Algol-60 disproves your theory. (How about Algol-58?)
>The rest of your post is similarly perceptive, as well.
Algol-60 was not *a* language - it was at least three. In fact, each implementation could almost be considered a different language, as far as syntax details. Remember I also mentioned a language couldn't be popular if it gave up very much that programmers took for granted. FORTRAN could be run almost unchanged on any system. Algol? Good luck...
In article <5cb4c7$...@sparky.franz.com>, Kelly Murray <k...@franz.com> wrote:
>In article <5c81q2$...@epx.cis.umn.edu>, thorn...@cs.umn.edu (David H. Thornley) writes: >>> >* D. J. Bernstein >>> >| unsigned long u,v; >>> >| v += u; >>> >| if (v < u) overflow();
>This doesn't work in complex expression with subexpression,
> v = ((u + 10) * (v + 4))
Personally, I'd do something like:
...as soon as you have your values... if( (u > MAXUINT-10) || (v > (MAXUINT / (u+10)) - 4) ) { error_function("An error occurred at *this* point."); /* The expression below is *not* an error. */ }
...sometime later...
v = ((u + 10) * (v + 4));
See, I think the issue of security/safety is not a language issue, but a programming issue.
In article <3063147946409...@naggum.no>, Erik Naggum <e...@naggum.no> wrote:
| $ time lotto | 4.42user 0.04system 0:04.50elapsed 99%CPU | | in CMUCL 17f, (time (lotto 35 7)) reports: | 2.15 seconds of real time
Just for chuckles, I tried the C and Lisp code with gcc and gcl, respectively, on a P6/200 running Linux. GCC: 0.30 seconds; GCL: 56.9 seconds. GCL doesn't seem to understand the (debug) declamation though, though it did understand the other optimizations. Maybe that's why it is so slow?
This presents so many opportunities! We can segue into a Linux vs SunOS flamewar, a Sparc vs x86 flamewar, a Gnu vs CMU flamewar.... The C vs Lisp flamewar is definitely starting to wear out.
In article <1997Jan24.113633.6...@jarvis.cs.toronto.edu> berne...@eecg.toronto.edu "Robert Bernecky" writes:
> I believe the two sides of the argument boil down to:
> a. Programmers need "safe languages" that handle such problems > automatically, so that average programmers can write > programs that are likely to work correctly under a large > set of operational conditions.
> b. Programmers need "efficient languages" that let an expert programmer > write Really Fast Code. Average programmers should be using > spreadsheets or be willing to take the time to learn all > the nasty things about the language they are using. > You can't use a knife if it's dull, and if it's sharp, you > might get cut if you don't use it carefully.
I agree. Remember the Douglas Adams joke about which is the superior species: humans or dolphins. Both think that _they_ are the superior species, and for exactly the same reasons.
That's why I don't expect this thread to lead to any profund discoveries or conclusions, for most of us, at least. We believe whatever we do because we're either a human or a dolphin - and no amount of discussion will change that. If it could, then it's likely to have happened some time ago.
The real effect that this thread may hav, constructive or otherwise, will be on those who are reading it but whose feelings and thoughts on this subject have not yet fossilised (by whatever means, e.g. positive or negative experiences, propaganda, brainwashing, enlightenment, etc).
> I think both sides have their virtues, but I'll present one data point:
> On Black Monday on Wall Street, there were several > ways that computers brought doom onto their trading users:
> a. Slow computers gave traders information that was many > hours out of date. Traders used this information to trade > themselves (and their banks) into deeper pits.
> b. Integer overflow (trade volumes, scaled currencies, etc) > caused systems to crash if the systems detected the overflow,
> c. Integer overflow caused Very Wrong Answers if modulo arithmetic > was performed. This also gave traders Bad Advice.
> Now, Morgan-Stanley Bank actually did NOT lose money on Black Monday. > They actually made a small (by their standards. It was probably enough to > finance a small war somewhere) profit that day. Their systems > were written in APL. The APL system detected integer overflow, > switched to floating point where needed, and kept going, giving them > good answers on time.
> I consider this an argument for safe languages.
<grin> There's also the Seymour Cray quote, but all that does is remind us, in this context, that we can choose speed or accuracy, but not necessarily _both_. Cray favoured speed, while sacrificing accuracy, which is a fair choice for the machines he designed, and the people who use them.
Not everyone will make the same choice, dispite the propaganda. While Alan Perlis once said that, "Lisp programmers know the value of everything and the cost of nothing", he could just easily be paraphrased, "C programmers know the cost of everything and the value of nothing".
So, C and Lisp programmers appear to make different choices. I wouldn't call that a profund statement. It _should_ be very obvious. Why then do so many of us miss this point, or forget about it? Why do people feel so strongly about which language _other people_ choose to use? Perhaps it's because we may have to use their software, or that some of us feel that these choices may effect them, and possibly limit _their_ choices?
I don't know. I use the tools that I do _because I can_. If anyone has a problem with that, I'll remind them to get a life. I'll not call them stupid, but I _will_ object to anyone who thinks that they can tell me which choices to make.
You're all welcome to _offer_ me advise, but please understand that I'm not obliged to follow it. ;-) That seems to me to be a healthy attitude. If not, then I'm sure someone will tell me... -- <URL:http://www.wildcard.demon.co.uk/> You can never browse enough Martin Rodgers | Developer and Information Broker | London, UK Please remove the "nospam" if you want to email me. "Blow out the candles, HAL."
In article <5cbasc$...@web.nmti.com> pe...@nmti.com "Peter da Silva" writes:
> It's too bad there aren't a lot of cheap efficient easily integrated Smalltalk > compilers out there.
There are one or two, if you look for them. Cheap, certainly. Efficient? That depends on how you define it. A few months ago, I saw a C programmer, somewhere on UseNet, slagging off VB and Delphi for not supporting threads, and therefore not being "efficient", in his eyes, enough for writing an NT service.
However, there's at least one Smalltalk that supports threads, and it's available for the same platform as VB and Delphi.
If I wanted to make an equally cheap shot at C, I'd ask where I can get find an "efficient" C compiler - one that compiles single functions fast enough so that I never notice it. Delphi can do that, and so can a number of Lisp compilers, all with native code as the result. Plus, how much memory is needed to do this? Lisp and Delphi can do it with as little as 16 MB, while (intentionally biasing the argument to make my point about bias!) I've not yet found a C++ compiler that can do the same using an identical platform.
Of course, I've not tried all of the available C++ compilers for this platform, so I confess that I'm not being fair. I'm not sure about your argument. What do qualities do _you_ look for in an "efficient" compiler?
I'm not sure that many people really care about this, judging by the popularity of slow compilers for C++. If enough of us wanted an fast edit/compile/run cycle, then C++ might be a very different language, or at least the compilers might be different.
It's the humans and dolphins issue, yet again. -- <URL:http://www.wildcard.demon.co.uk/> You can never browse enough Martin Rodgers | Developer and Information Broker | London, UK Please remove the "nospam" if you want to email me. "Blow out the candles, HAL."
In article <5c914e$...@fido.asd.sgi.com> mike...@engr.sgi.com (Mike McDonald) writes: >> * Robert Harley >>| So you complain about how obscure this check is in C: > Let's see, > v = -1; > u = 1; >>| v += u; >>| if (v < u) overflow(); > Whoops! I've got overflow. Dang, I've been getting overflows all these >years and never knew it. :-)
Perhaps because you missed the fact that u and v were declared as unsigned longs in preceding postings.
In article <3063055314263...@naggum.no> Erik Naggum <e...@naggum.no> writes: >* David Hanley >| Then why did't they flunk out of the SE class? >why do you think they had an SE class? >haven't you noticed that those who have software engineering and have a >computer science education don't usually write software in C?
[...]
I've had Software Engineering both as an undergrad and graduate student of Computer Science, and I now work for a company that uses C for its embedded systems development. Am I really that unusual, or are you just unable to see too far beyond your immediate surroundings?
In article <3063183095872...@naggum.no>, Erik Naggum <e...@naggum.no> wrote:
> * Scott Schwartz > | Just to be fair, you ought to measure the same thing. In the first > | case you measure the time to load and initialize the C runtime system. > | In the second case you already have Lisp fired up, so you omit the > | measurements for the cost of doing that. Let's see the time for the > | a.out generated by ACL or CMUCL, starting at the shell prompt. > right. the usual reaction from "C just _has_ to win"-people is to force > everything to fit its paradigm. when C loses by a factor of 2, it has to > be explained away with some nonsense like the above.
Fine. Rewrite the C code to time itself. You don't have to fit everything into the UNIX model to get a fair benchmark, you can fit everything into the Lisp model. Embed the C code in Tclsh or something, if that bothers you. You're comparing UNIX to the interpreter, not Lisp to C.
(and, no, C doesn't always win. Maclisp was already beating GOOD Fortran compilers many years ago, so I wouldn't be surprised to find that your CMUCL still beat C on a fair benchmark... but *do* run a fair one, eh?) --
> While Alan Perlis once said that, "Lisp programmers know > the value of everything and the cost of nothing", he could > just easily be paraphrased, "C programmers know the cost > of everything and the value of nothing".
Actually, you don't need to paraphrase; he said this much more directly. The quote - I heard it many times, in, most likely, all four of the different forms implied by the following - was:
"[C|Unix] has set back the state of computer science [10|15] years".
This was after his Epigrams were collected as Yale tech report - at the time that report was produced, neither C nor Unix were very wide-spread, and it was possible to believe that OS's and languages of the future would build on high-level constructions like TOPS-20, APL, and LISP - so it doesn't appear in the published lists.
In comp.lang.scheme D. J. Bernstein <d...@koobera.math.uic.edu> wrote:
> In article <3063147946409...@naggum.no>, Erik Naggum <e...@naggum.no> wrote: > > and in some cases, CL far exceed the wettest dreams of C programmers. > Expand the tail recursion in C, like this--- > Of course, it's bad to use the stack for temporary space. Allocate what > you need at the beginning, handling out-of-memory explicitly rather than > crashing, and use some obvious dynamic programming--- > ---for another 500x speedup. How would you translate that to LISP? How > fast is the result? > The code can still be substantially improved; e.g., the u array should > be duplicated to allow vectorization. There are also much better > algorithms for computing this function, but that's a side issue.
I don't normally respond to such obvious flame bait, but I have to put my $0.02 in, here. And, I'd like to ask what I think is an obvious question.
Mr. Bernstein spent most of his message tweaking the C code to make it faster. Mr. Naggum did some (quite necessary, in my opinion) clean-up of Mr. Bernstein's code. In my opinion, this small part of the overall exchange illustrates that Mr. Naggum's original point ("in some cases, CL far exceed the wettest dreams of C programmers.") is not supported by his example program. (I make no claims about any other sample programs.)
On the other hand, I am a firm believer in the methods of Kernighan and Plauger. As such, I am philosophically opposed to the sort of "tweaking" that Mr. Bernstein engages in. The cleanup required to make the tweaked code not leak memory like a sieve leaks water shows that it isn't quite as easy to get the code correct as it looks. I am, after all, not interested in code that gets the wrong answer with blazing speed. Neither am I interested in code that kills my computer (or is killed by my computer) when I try to run it.
Instead, I point out that computer programs have two speeds, fast enough and too slow. Certain algorithms (the one used in "lotto" is an example) are fast enough for small cases but will quickly become too slow for somewhat larger cases. (Instead of (lotto 35 7) try (lotto 60 30) or (lotto 100 50), and you'll see what I mean.) In the most general case, it is the limitations of the algorithm that will dominate the performance of the program, not the (mostly mythical) performance capabilities "of the language" or of one of the implementations of that language.
The question I ask is about the "much better algorithms for computing this function." In a cursory effort, I was unable to find any such thing, and I'm curious. Is there one that is linear in both "n" and "m"? What are these better algorithms? Anyone have any references?
-- Jonathan Guthrie (jguth...@brokersys.com) Information Broker Systems +281-895-8101 http://www.brokersys.com/ 12703 Veterans Memorial #106, Houston, TX 77014, USA
We sell Internet access and commercial Web space. We also are general network consultants in the greater Houston area.
Cyber Surfer <cyber_sur...@wildcard.demon.co.uk> wrote: > In article <5cbasc$...@web.nmti.com> pe...@nmti.com "Peter da Silva" writes:
> > It's too bad there aren't a lot of cheap efficient easily integrated Smalltalk > > compilers out there. > There are one or two, if you look for them. Cheap, certainly.
I'd appreciate any pointers you can give me.
> If I wanted to make an equally cheap shot at C,
I'm sorry if you thought I was taking a cheap shot. Smalltalk is by far my favorite language... but it's been mostly a platonic relationship because I haven't been able to get a smalltalk development platform on a wide enough range of boxes for me to use. I'm not anti-smalltalk, just frustrated.
As for C++, well, so far as I'm concerned C++ is the devil's work. Forget it. I'm not going to touch it unless I'm paid a lot of money to do so.
> It's the humans and dolphins issue, yet again.
No, I think you're either reading my messages *very* selectively or you're just jumping to conclusions without bothering to read them at all. --