On Mon, Jul 13, 2009 at 3:11 PM, Morgan Allen <alfred.morgan.al...@gmail.com
> wrote:

> It's a shame about the lack of official support for java-side
> invocation- the bulk of my code is still implemented in java (largely
> for efficiency reasons), so it would be handy to be able to initiate
> things largely from that side.


It's definitely not necessary to implement the bulk of your code in Java to
get performance. On the other hand, getting performance out of Clojure can
be tricky.

First, you need to know how to use loop/recur, type hints, primitives, and
such, not just separately but in harmony. With that, you can get inner loops
that will run, on the server VM, at C-code speeds, not unlike a tight loop
in Java that avoids method calls.

Second, if you need significant flexibility and variability and conditioning
in those loops, but not inside any given instance of running a loop for a
while, you need to get comfortable with macros -- backquote, unquote and
unquote-splicing, gensyms, and the works. With those, you can customize the
loop at each site in the program code so that decisions that don't have to
be made every iteration are made entirely outside of the loop, and each loop
instance has a particular, optimized form built in. This will give you
flexibility coupled with blazing speed.

I currently have a project on the go that has performance-critical CPU-bound
work that involves an open-ended, runtime-changeable set of parameters; a
simulation of sorts. I have it running probably faster than C code could
manage, because it actually uses eval and programmatically-constructed code
to compile new functions on the fly to do the bottleneck parts of the
computations. The resulting functions would be nightmares to code and
maintain individually, modify as needed, and so on, but then so would
assembly language. Basically, I went beyond domain-specific language and
wrote a domain-specific optimizing compiler that ultimately punts to
Clojure's.

Of course, eval is evil and this program will not run on hypothetical future
micro-edition deployment environments whose Clojure runtimes lack
eval/compiler support, but it will run on netbook and larger classes of
device at speeds that would make experienced C coders and assembly
hand-tuners turn green. Of course I can't take all the credit. Rich's
Clojure to bytecode compiler sits beneath my compiler, and Sun's Hotspot
Server VM JIT compiler sits beneath that in turn, and with either shoddy or
missing I couldn't get this kind of speed.

But it is proof that any needed speeds can be achieved in Clojure that can
be achieved in Java, or even by hand-hacking directly on the bare metal, or
by anything short of overclocking chips or fabricating new ones.

(Think of the future, too. Clojure macro-like code that compiles directly to
FPGA circuit layouts or programmable spintronic arrays or suchlike. Well,
not directly; it would be the JVM JIT that would be responsible for creating
hardware acceleration or extra cache memory on the fly for code bottlenecks,
and reallocating the finite gate-array real-estate dynamically as the needs
of the app demanded. Still, combining that with the ability to emit new
optimized JVM bytecode on the fly at need and you've got the ultimate in JIT
capabilities.)


>  I *was* planning to write up some
> interfaces for more frequent/time-critical communications, but having
> to compile things via ant or the command line is a pain, and Eclipse
> doesn't have particularly good support for mix-and-match of java and
> clojure files in the same project (at least atm.)


NetBeans, which I use, does better at this. You have to restart the REPL
after any change to Java classes, which is a nuisance, but you don't have to
restart the IDE or muck with anything else (project libraries, classpath).
Even if you have separate projects and some are dependencies of others, and
all are undergoing active development, you just have to reboot the REPL
after changing Java code. Changing Clojure code, even in a separate project
that's a dependency of your main project, can typically be handled with a
load-file of the changed file. Only if your refactoring moves a Clojure
function or other object from one namespace to another (same or different
project) do you generally have to restart the REPL, since it won't let you
intern a name in a package that imports the same name from another one, and
uninterned symbols won't go away. It's a good idea to occasionally restart
your REPL anyway to clear out cruft and avoid having a running image that's
become dependent on something that isn't in your code base, and also to find
anywhere where you are missing forward-declarations.

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to