Can access by local method variables be faster then access by member variables ?
Charles Oliver Nutter
charles.nutter at sun.com
Fri Aug 15 15:44:12 PDT 2008
I'll be interested to hear from the HotSpot engineers, but a few things
I know might help:
- local variables will be allocated on the stack and will be much hotter
in the cache
- obviously member variables are going to need to load and dereference
for every access, which would be slower than just retrieving a local
variable, with or without pushes and pops
- fields can obviously incur some cross-thread perf penalty if they
result in memory caches getting wacked, which you would not have
accessing local vars
- When we're able to move Ruby local variables from a heap-based
structure to local variables (stack-based) in JRuby, we see a tremendous
improvement in performance. It's probably the single largest perf boost
we get from compilation.
- Charlie
Ulf Zibis wrote:
> Hi experts,
>
> to avoid stack push + pop of src, dst I have refactored my code in
> moving the local method variables (sp, ...) to member variables (srcPos,
> ...).
>
> After this I have experienced that my code was little slower.
>
> For full source code see:
> https://java-nio-charset-enhanced.dev.java.net/source/browse/java-nio-charset-enhanced/trunk/src/sun/nio/cs/SingleByteEncoder.java?rev=291&view=markup
>
> https://java-nio-charset-enhanced.dev.java.net/source/browse/java-nio-charset-enhanced/trunk/src/sun/nio/cs/SingleByteEncoder.java?rev=302&view=markup
>
>
> ======================================== revisions 291
> ========================================
>
> private CoderResult encodeArraysLoop(CharBuffer src, ByteBuffer dst) {
> char[] sa = src.array();
> int sp = src.arrayOffset() + src.position();
> int sl = src.arrayOffset() + src.limit();
> assert (sp <= sl);
> byte[] da = dst.array();
> int dp = dst.arrayOffset() + dst.position();
> int dl = dst.arrayOffset() + dst.limit();
> assert (dp <= dl);
> try {
> for (; sp < sl; sp++) {
> current = sa[sp];
> byte b = encodeSingle();
> if (dp >= dl)
> return CoderResult.OVERFLOW;
> da[dp++] = b;
> }
> return CoderResult.UNDERFLOW;
> } catch (UnmappableCharacterException e) {
> if (Surrogate.isLow(current) || current >= '\uFFFE')
> return CODERRESULT_MALFORMED;
> if (Surrogate.isHigh(current))
> try {
> if (sp+1 >= sl)
> return CoderResult.UNDERFLOW;
> encodeSurrogate(sa[sp+1]);
> } catch (UnmappableCharacterException e2) {
> return CODERRESULT_UNMAPPABLE2;
> } catch (MalformedInputException e2) {
> return CODERRESULT_MALFORMED2;
> }
> return CODERRESULT_UNMAPPABLE;
> } finally {
> src.position(sp - src.arrayOffset());
> dst.position(dp - dst.arrayOffset());
> }
> }
>
> ======================================== revisions 302
> ========================================
>
> private CoderResult encodeArraysLoop() throws RuntimeException,
> UnmappableCharacterException {
> for (; srcPos < srcLimit; srcPos++) {
> current = srcArray[srcPos];
> byte b = encodeSingle();
> if (dstPos < dstLimit)
> dstArray[dstPos++] = b;
> else
> return CoderResult.OVERFLOW;
> }
> return CoderResult.UNDERFLOW;
> }
>
> ===============================================================================================
>
>
>
> Thanks for your explanations,
>
> Ulf
>
>
>
>
More information about the hotspot-dev
mailing list