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 -~----------~----~----~----~------~----~------~--~---