Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Structure Performance #1625

Closed
brettwooldridge opened this issue Sep 20, 2024 · 0 comments · Fixed by #1626
Closed

Structure Performance #1625

brettwooldridge opened this issue Sep 20, 2024 · 0 comments · Fixed by #1626

Comments

@brettwooldridge
Copy link
Contributor

brettwooldridge commented Sep 20, 2024

This is likely somewhat related to #1616, or rather #1616 could be addresses as part of a fix for this. It seems that the initialization of a Structure is extremely expensive.

For example, the NuProcess project has a structure like the following:

public static class Kevent extends Structure
{
   public NativeLong ident;
   ...
   public Kevent() {
       super();
   }
   ...

And millions of these structures get created/destroyed per minute of execution.

In a profiler, the initialiation of the super class Structure shows up very high. In particular, the calls to validateFields() and initializeFields() are very expensive:

protected Structure(Pointer p, int alignType, TypeMapper mappe
    setAlignType(alignType);
    setStringEncoding(Native.getStringEncoding(getClass()));
    initializeTypeMapper(mapper);
    validateFields();                                      <--- HERE
    if (p != null) {
        useMemory(p, 0, true);
    }
    else {
        allocateMemory(CALCULATE_SIZE);
    }
    initializeFields();                                    <--- HERE
}

But given the static nature of Structures, it seems like all of the work done in validateFields() could be cached such that all of the heavy java.lang.Reflection work does not need to be performed for every new instance of that Structure. The fields are not changing and therefore "validation" does not need to be continually performed.

Am I correct?

Or does the fact that layoutChanged() exists imply that may not be so? Then again, that only appears to be the case when a TypeMapper is in play, so maybe caching would still work in the case that TypeMapper is null.

Similarly, initializeFields() calls getFieldList() which performs a boatload of reflection on fields that cannot change dynamically, and it does this for every instance construction. Using a cached field list would certainly cut down on the contention reported in #1616 while greatly speeding up the code.

Again, is this a valid observation? If these are valid observations, I will happily submit a pull request addressing these two issues, awaiting feedback here.

brettwooldridge added a commit to brettwooldridge/jna that referenced this issue Sep 20, 2024
…idation state in addition to the existing layoutInfo and fieldOrder caches.
brettwooldridge added a commit to brettwooldridge/jna that referenced this issue Sep 20, 2024
…idation state in addition to the existing layoutInfo and fieldOrder caches.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant