Arc Forumnew | comments | leaders | submitlogin
Arc omptimization, again
5 points by sacado 6105 days ago | 9 comments
Yes, Arc's primary targets are webapps and prototypes. But I don't only write webapps and don't want to rewrite my prototypes in another language once they work fine but are too slow :

  * I have better things to do
  * I will probably have to add new features later on, and Arc is especially good at that.
Thus, I was thinking about optimizing a little the arc interpreter. As Paul suggested in an old post, I looked at the code the ac function in ac.scm generates. ac is the function that translates a form in Arc in its mzscheme counterpart.

Well, the sad truth is that, for example, something as trivial as the list function becomes, once expanded (this is still arc code) :

((fn () (sref sig (quote args) (quote list)) (if (is (type (quote " Creates a list from the given parameters.\n See also [[cons]] [[acons]] ")) (quote string)) (sref help (quote (fn " Creates a list from the given parameters.\n See also [[cons]] [[acons]] ")) (quote list)) (sref help (quote (fn nil)) (quote list))) (sref source-file current-load-file (quote list)) (safeset list (fn args " Creates a list from the given parameters.\n See also [[cons]] [[acons]] " args))))

And its scheme translation is

((lambda () (ar-funcall3 _sref _sig (quote args) (quote list)) (if (not (ar-false? (ar-funcall2 _is (ar-funcall1 _type (quote " Creates a list from the given parameters.\n See also [[cons]] [[acons]] ")) (quote string)))) (ar-funcall3 _sref _help (quote (fn " Creates a list from the given parameters.\n See also [[cons]] [[acons]] " . nil)) (quote list)) (ar-funcall3 _sref _help (quote (fn nil . nil)) (quote list))) (ar-funcall3 _sref _source-file _current-load-file (quote list)) ((lambda () (if (not (ar-false? (ar-funcall1 _bound (quote list)))) ((lambda () (ar-funcall1 _disp "* redefining ") (ar-funcall1 _disp (quote list)) (ar-funcall1 _writec #\newline))) (quote nil)) (begin (let ((| list| (lambda args " Creates a list from the given parameters.\n See also [[cons]] [[acons]] " args))) (namespace-set-variable-value! (quote _list) (lambda args " Creates a list from the given parameters.\n See also [[cons]] [[acons]] " args) #t arc-ns) | list|))))))

Argh. Quite a few things to optimize there (I am quite surprised, for example, to see that the docstring is repeated so many times. Even without it, it's quite a big form). Guess why it takes so long before you get the arc prompt ?

In the same vein as arc-exe.scm I wrote a few days ago, I wanted to make an arc compiler, something transforming arc code in its scheme equivalent, then compiling it through the mzc utility, at least for the arc.arc and libs.arc files. Well, it's far to be easy.

Has anybody tried to do such a thing as optimizing these things yet ? Have you got any idea about how we could get that better ? Do you think it will only bring a minor optimization ?



6 points by kens 6105 days ago | link

When I looked at benchmarking earlier (http://arclanguage.org/item?id=2455) I discovered that the performance hits were very different from what I was expecting. (I.e. in my case, it wasn't the function call overhead, but the < operator of all things.) My point is that if you optimize Arc, make sure you measure carefully, rather than assume you know where the performance goes. (I also found that performance is one of those things you're not supposed to discuss, a la http://www.paulgraham.com/say.html)

In my brief examination of the Arc internals, I didn't see any obvious optimizations. The ac-niltree/ac-denil stuff seems like there should be a better way. The conversion between nil and #f (e.g. ar-false? in your code above) seems like excessive overhead. But I don't see any better alternative.

-----

4 points by lojic 6105 days ago | link

Are you actually experiencing a problem now, or just anticipating one? I currently program primarily in Ruby which is one of the slower languages around, and I've yet to max out a CPU with a web app, and I simply wouldn't use Ruby for serious number crunching.

Maybe my view is a naive one, but I feel that if Arc is successful, the effort to improve performance will be made.

On the other hand, it is a bit strange to see the docstring repeated like that.

-----

1 point by sacado 6104 days ago | link

Well, that's actually what kept me from Ruby and made me stick with Python for a while. I needed a little speed. Not that much, but Ruby was just below the barrier.

-----

4 points by elibarzilay 6105 days ago | link

Repeating any single string several times looks bad (and might be bad for other reasons), but should not lead to a performance hit. Consider the fact that each of these occurrences that you see is just a pointer to the single string that was created when the code was read in.

-----

1 point by sacado 6105 days ago | link

I was wondering, about the delay during the initial interpretation of (load "arc.arc") and (load "libs.arc") everytime arc is invoked : is that possible to load (and eval) these files once in mzscheme and then save the whole memory in an executable, à la SBCL (maybe other CLs, too) ? I couldn't find it in mzc's doc or in mzscheme's functions, at least in the older versions. That will not solve the problems after loading, I guess, but this one is quite boring (I find).

-----

1 point by elibarzilay 6103 days ago | link

It is possible to byte-compile it, which will get rid of the delay. It is also possible to create an executable with the compiled files in.

-----

4 points by tel 6105 days ago | link

I definitely understand the desire to optimize...

... but doesn't this seem like a pretty quintessential example of premature optimization?

-----

3 points by sacado 6104 days ago | link

Yes,but no. Once you get in the code of ac.scm, you see that the code is great (really easy to understand everything) but that it can really be optimized in trivial ways.

We already talked about arc<. The original code was : if all the elements are numbers, apply numeric + to the args. If all are strings, apply string-append. If all are lists, apply append. Else, apply numeric + (again). The optimization is obvious there, and I don't think it can be called premature.

There was another one that was fixed by pg in Arc2 (for those interested, it deals with ar-funcall).

I know I wasn't clear. I don't want Arc as fast as light right now. What really bugs be is the fact that I have to wait 3 seconds before I get the prompt. When arc.arc and libs.arc are loaded. That's what I would like to see optimized, as soon as possible.

-----

1 point by sacado 6105 days ago | link

Obviously, the code of Arc2 in ac.scm has been rewritten in some places, leading to optimisations in some cases but to slowdowns in other places. For example, (fib 10) is about 5 times (!) slower, but (fib 35) is about 30% faster. Maybe there are still easy optimisations possible.

btw, pg's code has been replaced by the older's code on the git, I'll fix that later on.

-----