Re: Jde-complete performance
"Suraj Acharya" <[email protected]>
| Newsgroups | gmane.emacs.jdee |
|---|---|
| Message-ID | <[email protected]> |
Hi Nascif, CVS jde-usages has two exprimental features 1) an implementation of getClassInfo which uses the jde-usages data structures : (defalias 'jde-complete-invoke-get-class-info 'jde-usages-complete-invoke-get-class-info) 2) A slightly reworked jde-parse-eval-type-of which changes the order in which in tests for the type of the input. The main change is that it defers the expensive call to jde-parse-get-qualified-name as long as possible if the suspected class name does not match the usual class name convention, eg "FooBarBaz". (defalias 'jde-parse-eval-type-of 'jde-usages-parse-eval-type-of) There are also some other functions that replace JDEE java code by using the jde-usages structures: (defalias 'jde-parse-get-qualified-name 'jde-usages-parse-get-qualified-name) (defalias 'jde-parse-class-exists 'jde-usages-parse-class-exists) These features are exprimental because I don't have any regression tests yet for them, and have not done any exhaustive tests to look for differences from the jde behaviour, however I use emacs with these features turned on and fix bugs as I find them, so they're quite stable and usable. See the CVS release notes and change log under usages/web. Suraj On 4/11/06, Nascif Abousalh-Neto <[email protected]> wrote: > > Hi all, > > I am aware that JDEE has an "intellisync" feature implemented in the > jde-complete family of methods. To be honest I don't use it much for two > reasons: 1) it doesn't always work and 2) it is very, very slow. It usually > takes on the order of 13-15 seconds for it to return, and in the mean time > it locks everything in Emacs. Even if it is just a first time impact since > the class information is cached, still is quite a long time to wait. > > I looked at the code, and I found this interesting bit: > > (defun jde-complete-get-classinfo (name &optional access-level) > > ... > > (let ((class-info (jde-complete-get-from-cache name)) > public-methods protected-methods private-methods > package-methods) > (when (not class-info) > ;;Getting public class info > (setq public-methods > (jde-complete-invoke-get-class-info > name jde-complete-public)) > > ;;Getting protected class info > (setq protected-methods > (jde-complete-invoke-get-class-info > name jde-complete-protected)) > > ;;Getting package class info > (setq package-methods > (jde-complete-invoke-get-class-info > name jde-complete-package)) > > ;;Getting private class info > (setq private-methods > (jde-complete-invoke-get-class-info > name jde-complete-private)) > (setq class-info (append public-methods > protected-methods > package-methods > private-methods)) > > The method jde-complete-invoke-get-class-info is called four times. On > each call it uses the BeanShell to invoke the following Java method in the > JDE utility class Completion.java: > > public static void getClassInfo(String className, int level) { > try { > DynamicClassLoader dcl = new DynamicClassLoader(); > Class c = dcl.loadClass(className); > if (c != null) { > StringBuffer sb = new StringBuffer (3000); > sb.append(START_LIST); > sb.append(NL); > listClassInfo(c, level, sb); > sb.append(END_PAREN); > sb.append(NL); > > Writer out > = new BufferedWriter(new OutputStreamWriter(System.out)); > try { > out.write(sb.toString()); > out.flush(); > } catch (IOException e) { > } > } > > So we have four separate round trips from the Emacs Lisp world to the Java > world, which are quite expensive; plus we create four separate instances of > DynamicClassLoader created. And this guy seems to be quite expensive as > well, since according to the documentation: > > * The class <code>DynamicClassLoader</code> extends the > * abstract class <code>ClassLoader</code>. > * This class loads the class binaries from the file system > * all the time, it does not catch the class information. > > Theoretically then we read the each jar and class file in the classpath > four times for each call to jde-complete on a new class... I have not yet > run all this process through a profiler (planning to) but it seems to me > that making just one call that gets the complete class info and returning > four lists (one for each access level) would be far less expensive, since it > would allow the DynamicClassLoader to be reused and reduce the number of > Emacs-Java calls. > > Is that a fair assessment? Or is there a reason for this code to be this > way that I am not aware of? > > Also, we have a parallel method to read class information in the > jde-usages package, that uses the ASM library. Which one is more efficient? > Wouldn't it be benefitial to unify the two methods so that JDEE has one > single source of (hopefully cached) class information for usage, completion > and one day quick fixes and other simple refactorings? > > Thanks, > Nascif >