Skip to content

Make Jmeter able to support nanoseconds for testing and reporting #6406

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

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

junyejiang
Copy link
Contributor

@junyejiang junyejiang commented Jan 10, 2025

In my test experience, when the performance of the system under test is much too fast (for example, when testing Redis), the milliseconds is too large to reflect the performance of the system under test, so the following changes are made:

  1. Change the unit of Jmeter Result from milliseconds to nanoseconds.
  2. Statistical calculations use BigDecimal/BigInteger to make the statistical results more accurate and no overflow.
  3. The test report uses ms/ns as the final output unit according to the Properties configuration.

Description

Motivation and Context

How Has This Been Tested?

Screenshots (if appropriate):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Checklist:

  • My code follows the code style of this project.
  • I have updated the documentation accordingly.

…is much too fast (for example, when testing Redis), the ms is too large to reflect the performance of the system under test, so the following changes are made:

1. Change the unit of Jmeter Result from ms to ns.
2. Statistical calculations use BigDecimal/BigInteger to make the statistical results more accurate and no overflow.
3. The test report uses ms/ns as the final output unit according to the Properties configuration.
Copy link
Collaborator

@vlsi vlsi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have not checked the way the report works, however, I have a few comments:

  1. Have you checked sampleresult.useNanoTime JMeter property? If so could you describe why the property is not enough for you?
  2. Please refrain from modifying the existing tests. In most cases, if you modify an existing test it means you break backward compatibility which is unwanted.
  3. Please create new tests for the feature you add
  4. Please refrain from combining multiple unrelated changes into a single commit. I think the change of double -> BigDecimal should be discussed and measured separately

/**
* StatCalculator for Long values
*/
public class StatCalculatorLong extends StatCalculator<Long> {
public class StatCalculatorLong extends StatCalculator<BigInteger> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The signature change would break backward compatibility, so previous usages would become invalid. I'm not sure breaking JMeter clients is the right thing to do.

Comment on lines +43 to 46
private BigDecimal sum = BigDecimal.ZERO;

private double sumOfSquares = 0;
private BigDecimal sumOfSquares = BigDecimal.ZERO;

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this change belong to "support nanoseconds" PR?
If you want to improve precision of StatCalculator, I would suggest creating a separate PR and discuss it there.

Have you checked if the change from double to BigDecimal produces no significant performance regressions?

Comment on lines 69 to 73
calculator.addSample(SampleResult(10 * 1000000L, 40 * 1000000L))
assertEquals(40.0, calculator.mean, 0.001, "mean(40)")
calculator.addSample(SampleResult(10, 42))
calculator.addSample(SampleResult(10 * 1000000L, 42 * 1000000L))
assertEquals((40.0 + 42.0) / 2, calculator.mean, 0.001, "mean(40, 42)")
calculator.addSample(SampleResult(10, 48).apply { sampleCount = 2 })
calculator.addSample(SampleResult(10 * 1000000L, 48 * 1000000L).apply { sampleCount = 2 })
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does not sound right to modify the existing tests. Please refrain from modifying the existing tests unless it is absolutely necessary.
Otherwise it looks like you break backward compatibilty as we can't require all the plugins to rewrite and recompile their code to add * 1000000L all over the place.

1551783686523,267,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
1551783686790,280,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
1551783687071,305,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
1551783627191000000,351000000,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please refrain from modifying the existing tests. Please create a new test for the feature you add.

@@ -34,6 +34,8 @@
# Reporting configuration
#---------------------------------------------------------------------------

jmeter.reportgenerator.msns=ms
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jmeter.reportgenerator.msns is a strange property name. Consider someone would need minutes later. I would suggest something like jmeter.reportgenerator.time.unit=ns|ms|minutes|....

However,

@junyejiang
Copy link
Contributor Author

junyejiang commented Feb 10, 2025

I have not checked the way the report works, however, I have a few comments:

  1. Have you checked sampleresult.useNanoTime JMeter property? If so could you describe why the property is not enough for you?
  2. Please refrain from modifying the existing tests. In most cases, if you modify an existing test it means you break backward compatibility which is unwanted.
  3. Please create new tests for the feature you add
  4. Please refrain from combining multiple unrelated changes into a single commit. I think the change of double -> BigDecimal should be discussed and measured separately
  1. Yes I did tried sampleresult.useNanoTime, and finally find out that report was still in ms, this property will not help.
  2. My PR do break backwark compatibility, as the former JTL file was stored in ms format, My PR will change it to ns format. So that the former tests wold not pass until updated.
  3. The same as Q2
  4. Changes in calculators from Long to BigDecimal is because, firstly every test timestamp is 1 million bigger than before so Long could be easily overflow during accumulation; secondly BigDecimal/BigInteger is more precise than Long in calculation.

@vlsi
Copy link
Collaborator

vlsi commented Feb 24, 2025

My PR do break backwark compatibility, as the former JTL file was stored in ms format, My PR will change it to ns format. So that the former tests wold not pass until updated.

I am afraid we can't merge such PRs then. We can't break everybody's workflows when releasing a new version.

@junyejiang
Copy link
Contributor Author

My PR do break backwark compatibility, as the former JTL file was stored in ms format, My PR will change it to ns format. So that the former tests wold not pass until updated.

I am afraid we can't merge such PRs then. We can't break everybody's workflows when releasing a new version.

Understood. Thanks.

@junyejiang junyejiang closed this Feb 26, 2025
@vlsi
Copy link
Collaborator

vlsi commented Feb 26, 2025

It would be great if we could support both formats at the same time, however, keeping the old scripts workable and old files parseable is important

@ra0077
Copy link
Contributor

ra0077 commented Feb 27, 2025

+1 to have the support of both formats

@junyejiang
Copy link
Contributor Author

It would be great if we could support both formats at the same time, however, keeping the old scripts workable and old files parseable is important

I will try to make it. Reopen this PR

@junyejiang junyejiang reopened this Mar 1, 2025
@junyejiang
Copy link
Contributor Author

junyejiang commented Mar 5, 2025

@vlsi
fd12dc3
Made following changes:

  1. Introduced new metadatas in csv, jtl and xml, these metadatas are dedicated to store ns timestamp, old metadatas are untouched.
    When Jmeter loads csv, jtl or xml, it tries to read and load ns timestamp first if possible, otherwise it goes the old fasioned way.
  2. Added new setter functions in SampleResult.java, these functions are ns timestamp related only, original constructors and factory funcions are untouched.

Above 2 changes are for backward compability.

  1. Renamed ns/ms key in reportgenerator.properies.
  2. Added test to check my changes.

If my PR is not accepted finally some how, I still suggest to update in calculators from Long to BigInteger/Bigdecimal, which brings better precision and will not cause overflow.

@junyejiang junyejiang requested a review from vlsi March 5, 2025 10:03
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 this pull request may close these issues.

3 participants