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