You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@jmeter.apache.org by "vlsi (via GitHub)" <gi...@apache.org> on 2023/06/04 19:40:27 UTC

[GitHub] [jmeter] vlsi opened a new issue, #5968: Optimize getPropertyOrNull(PropertyDescriptor) access with index-based storage

vlsi opened a new issue, #5968:
URL: https://github.com/apache/jmeter/issues/5968

   ### Use case
   
   JMeter often queries properties at runtime. For instance, `ResultCollector` `isSuccessOnlyLogging` and `isErrorLogging` call `getProperty(String)` which is cotly.
   
   
   ### Possible solution
   
   If test element schemas are specified with inheritance, then we could copy properties to an array where elements are `JMeterProperty` in their declaration order.
   Then access `getPropertyOrNull(PropertyDescriptor)` could be optimized with indices.
   
   For instance:
   
   ```kotlin
   public open class TestElementSchema protected constructor() : DefaultTestElementSchema() {
       public companion object INSTANCE : TestElementSchema()
   
       public val name: StringPropertyDescriptor<TestElementSchema> =
           string("TestElement.name")
       public val comments: StringPropertyDescriptor<TestElementSchema> =
           string("TestElement.comments")
   ...
   ```
   
   ```kotlin
   public open class ResultCollectorSchema: TestElementSchema() {
       public companion object INSTANCE: ResultCollectorSchema()
   
       public val successOnly: BooleanPropertyDescriptor<ResultCollectorSchema> =
           boolean("ResultCollector.success_only_logging")
   
       public val errorOnly: BooleanPropertyDescriptor<ResultCollectorSchema> =
           boolean("ResultCollector.error_logging")
   ```
   
   It would result in the following indices:
   
   ```
   0 name
   1 comments
   2 successOnly
   3 errorOnly
   ```
   
   Then, if we need to query `successOnly` at runtime, we can check if the element declares `ResultCollectorSchema` (or its subtype), and then we can access element `2` from properties array.
   
   Here's a sketch:
   
   ```java
   public class ResultCollector extends ... {
       public boolean isSuccessOnlyLogging() {
           return get(getSchema().getSuccessOnly());
           // return getPropertyAsBoolean(SUCCESS_ONLY_LOGGING,false);
       }
   
       public boolean isErrorLogging() {
           return get(getSchema().getErrorOnly());
           // return getPropertyAsBoolean(ERROR_LOGGING);
       }
   ```
   
   ```java
   public abstract class AbstractTestElement ... {
       private final transient JMeterProperty[] fastProps = new JMeterProperty[getSchema().getProperties().size()];
   
       // Optimized property access
       public JMeterProperty getPropertyOrNull(PropertyDescriptor<?, ?> key) {
           int index = key.getIndex();
           JMeterProperty[] fastProps = this.fastProps;
           if (index >= 0 && index < fastProps.length) {
               if (key.getSchema().isInstance(getSchema())) {
                   return fastProps[index];
               }
           }
           return getPropertyOrNull(key.getName());
       }
   
       // Every property store would store the property to fastProps array
       private void storeFastProperty(JMeterProperty prop) {
           PropertyDescriptor<?, ?> descr = getSchema().getProperties().get(prop.getName());
           if (descr != null) {
               int propIndex = descr.getIndex();
               if (propIndex >= 0 && propIndex < fastProps.length) {
                   fastProps[propIndex] = prop;
               }
           }
       }
   ```
   
   I assume we have only a few "property store" calls at the runtime, so it should be fine to perform extra work in `setProperty`, `remove(JMeterProperty)`.
   
   A draft benchmark (see `ResultCollectorBenchmark` in `core/src/jmh`) shows ~8ns for the current `isSampleWanted` and ~3ns with the optimized `getPropertyOrNull(PropertyDescriptor` case.
   
   It is not dramatic, however, it would be interesting to test it more.
   
   ### Possible workarounds
   
   _No response_
   
   ### JMeter Version
   
   5.5
   
   ### Java Version
   
   _No response_
   
   ### OS Version
   
   _No response_


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jmeter.apache.org.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org