[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: CompiledExpression.evaluate implementation
From: |
Konstantin L. Metlov |
Subject: |
Re: CompiledExpression.evaluate implementation |
Date: |
Tue, 17 Nov 2020 19:16:31 +0300 |
User-agent: |
SquirrelMail/1.4.23 [SVN] |
Dear Mark,
thank you for your suggestion ! I've done just that and also cleaned up
all the other JDK14 compiler warnings.
The valueOf may be slower to create an object in some cases, but note that
it also eliminates the need to free these objects. So, additionally to
using "valueOf" in the compiler itself, I've switched JEL code generator
to use it for creation of wrapper objects in the compiled expressions as
well.
I've made another pre-release version today with these changes available at
http://www.donfti.ru/~metlov/jel-2_1_2-pre2.zip
$ md5sum jel-2_1_2-pre2.zip
995daac05794b29109267815df76284e jel-2_1_2-pre2.zip
$ sha256sum jel-2_1_2-pre2.zip
f15e6e25b2d39f28c8a503cfd382c0361734a85c50d8e7e61195a2818d97ca43
jel-2_1_2-pre2.zip
Could you please download it and see if it does not break anything for you
? You can conveniently browse the source changes on Savannah:
http://svn.savannah.gnu.org/viewvc/jel/trunk/
Still, the best performance with JEL can be achieved by eliminating the
object usage altogether and using only the primitive types. This can be
done by fixing the result type in the Evaluator.compile call to one of the
Boolean.TYPE, Integer.TYPE, ... fields (note that these are not the
Boolean.class, Integer.class, etc) and then calling the corresponding
evaluate_boolean, evaluate_int, etc method of the CompiledExpression
directly. Setting the result type this way makes
CompiledExpression.getType() to always return the same value. The type
compatibility check (with widening conversion, if necessary) is then going
to be done by JEL at compile time.
With the best regards,
Konstantin.
> Konstantin,
>
> while I'm talking to you, I have another suggestion.
>
> In gnu.jel.CompiledExpression.evaluate you have this code:
>
> switch (type) {
> case 0: res=new Boolean(evaluate_boolean(dl)); break;
> case 1: res=new Byte(evaluate_byte(dl)); break;
> case 2: res=new Character(evaluate_char(dl)); break;
> case 3: res=new Short(evaluate_short(dl)); break;
> case 4: res=new Integer(evaluate_int(dl)); break;
> case 5: res=new Long(evaluate_long(dl)); break;
> case 6: res=new Float(evaluate_float(dl)); break;
> case 7: res=new Double(evaluate_double(dl)); break;
> case 9: evaluate_void(dl); break;
> ...
>
> What do you think about writing instead:
>
> case 0: res=Boolean.valueOf(evaluate_boolean(dl)); break;
> case 1: res=Byte.valueOf(evaluate_byte(dl)); break;
>
> since those methods avoid object creation by using pre-constructed
> Boolean/Byte object instances (see the advice in the javadocs
> for those static methods). The case is less clear for the other
> types; although the javadocs suggest that valueOf is "likely to
> yield significantly better space and time performance by caching
> frequently requested values" for all those wrapper class valueOf
> methods, I have sometimes found in tests that they are slower
> than using the constructors, presumably because of lookup overheads.
>
> Thanks for considering,
>
> Mark
>
> --
> Mark Taylor Astronomical Programmer Physics, Bristol University, UK
> m.b.taylor@bris.ac.uk +44-117-9288776 http://www.star.bris.ac.uk/~mbt/
>
>