commons-io icon indicating copy to clipboard operation
commons-io copied to clipboard

[IO-670] refine IOUtils.contentEqualsIgnoreEOL(Reader, Reader)

Open XenoAmess opened this issue 5 years ago • 50 comments

refine IOUtils.contentEquals(Reader, Reader) from simply wrapped by BufferedReader to something better.

XenoAmess avatar Jun 01 '20 16:06 XenoAmess

need I make a performance test case to show the performance?

XenoAmess avatar Jun 01 '20 16:06 XenoAmess

I also want to change other contentEquals functions in IOUtils (using similar way), but I want to listen to your advices first.

XenoAmess avatar Jun 01 '20 16:06 XenoAmess

Coverage Status

Coverage increased (+0.005%) to 89.4% when pulling eb25f9a554b8302b5bc870c6b0c960bd74a2f45c on xenoamess-fork:refine_contentEquals into c54bf688e94b550c3ccd4c0789e0b3e00cf1d0ea on apache:master.

coveralls avatar Jun 01 '20 16:06 coveralls

@XenoAmess

  • When you create a PR, please do not leave the description empty. It makes it harder to review.
  • If a PR claims a performance improvement, it must back it up; some components do this using JMH microbenchmarks, for example please see Apache Commons BCEL, Crypto, CSV, Lang, Math, RNG.

garydgregory avatar Jun 01 '20 17:06 garydgregory

@garydgregory

@XenoAmess

  • When you create a PR, please do not leave the description empty. It makes it harder to review.

OK

  • If a PR claims a performance improvement, it must back it up; some components do this using JMH microbenchmarks, for example please see Apache Commons BCEL, Crypto, CSV, Lang, Math, RNG.

I have only experiences using Jprofiler and I don't know how to embed a test with performance in junit. I'll learn about JMH microbenchmarks. thanks. update: I learned how to use it, thanks for your recommendation.

also, need I create more tests for testing wether this function is correct? or tests that already exist, which for the older function, is good enough and I need not create more?

XenoAmess avatar Jun 01 '20 17:06 XenoAmess

@garydgregory I will use this as example and change its content and add the test into this repo if you don't mind. https://github.com/apache/commons-lang/blob/5cdac9cfd5a74b0a52ebde32798b973c6edbaa79/src/test/java/org/apache/commons/lang3/HashSetvBitSetTest.java

XenoAmess avatar Jun 01 '20 17:06 XenoAmess

@garydgregory BTW, how can I show the performance result generated? simply paste it here?

XenoAmess avatar Jun 01 '20 17:06 XenoAmess

@garydgregory Performance test done. Conclusion: In cases for small content readers (a File), the new function is slightly faster. but in cases for large content (a String), the new function can be 6.5 times faster. Come to re-think of it, it MIGHT because, the FileReader is slow, so the delay of that function is kindof, hided, But StringReader is faster, so the difference is more significant.

D:\workspace\commons-io>mvn -Pbenchmark
[INFO] Scanning for projects...
[INFO]
[INFO] -----------------------< commons-io:commons-io >------------------------
[INFO] Building Apache Commons IO 2.7.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:3.1.0:clean (default-clean) @ commons-io ---
[INFO] Deleting D:\workspace\commons-io\target
[INFO]
[INFO] --- maven-enforcer-plugin:3.0.0-M2:enforce (enforce-maven-version) @ commons-io ---
[INFO]
[INFO] --- maven-enforcer-plugin:3.0.0-M2:enforce (enforce-maven-3) @ commons-io ---
[INFO]
[INFO] --- apache-rat-plugin:0.13:check (rat-check) @ commons-io ---
[INFO] Enabled default license matchers.
[INFO] Will parse SCM ignores for exclusions...
[INFO] Parsing exclusions from D:\workspace\commons-io\.gitignore
[INFO] Finished adding exclusions from SCM ignore files.
[INFO] 73 implicit excludes (use -debug for more details).
[INFO] 12 explicit excludes (use -debug for more details).
[INFO] 373 resources included (use -debug for more details)
[INFO] Rat check: Summary over all files. Unapproved: 0, unknown: 0, generated: 0, approved: 364 licenses.
[INFO]
[INFO] --- build-helper-maven-plugin:3.0.0:parse-version (parse-version) @ commons-io ---
[INFO]
[INFO] --- maven-antrun-plugin:1.8:run (javadoc.resources) @ commons-io ---
[INFO] Executing tasks

main:
     [copy] Copying 2 files to D:\workspace\commons-io\target\apidocs\META-INF
[INFO] Executed tasks
[INFO]
[INFO] --- maven-remote-resources-plugin:1.5:process (process-resource-bundles) @ commons-io ---
[INFO]
[INFO] --- buildnumber-maven-plugin:1.4:create (default) @ commons-io ---
[INFO] Executing: cmd.exe /X /C "git rev-parse --verify HEAD"
[INFO] Working directory: D:\workspace\commons-io
[INFO] Storing buildNumber: 73dc0ff3e6d79ab88f1ed0d253d52cb6da0dffa5 at timestamp: 1591034434847
[INFO] Storing buildScmBranch: refine_contentEquals
[INFO]
[INFO] --- maven-resources-plugin:3.1.0:resources (default-resources) @ commons-io ---
[INFO] Using 'iso-8859-1' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory D:\workspace\commons-io\src\main\resources
[INFO] Copying 2 resources to META-INF
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ commons-io ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 158 source files to D:\workspace\commons-io\target\classes
[INFO] /D:/workspace/commons-io/src/main/java/org/apache/commons/io/input/ClassLoaderObjectInputStream.java: Some input files use or override a deprecated API.
[INFO] /D:/workspace/commons-io/src/main/java/org/apache/commons/io/input/ClassLoaderObjectInputStream.java: Recompile with -Xlint:deprecation for details.
[INFO] /D:/workspace/commons-io/src/main/java/org/apache/commons/io/IOExceptionList.java: D:\workspace\commons-io\src\main\java\org\apache\commons\io\IOException
List.java uses unchecked or unsafe operations.
[INFO] /D:/workspace/commons-io/src/main/java/org/apache/commons/io/IOExceptionList.java: Recompile with -Xlint:unchecked for details.
[INFO]
[INFO] --- maven-bundle-plugin:4.2.1:manifest (bundle-manifest) @ commons-io ---
[INFO]
[INFO] --- animal-sniffer-maven-plugin:1.18:check (checkAPIcompatibility) @ commons-io ---
[INFO] Checking unresolved references to org.codehaus.mojo.signature:java18:1.0
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\input\TeeReader.java:158: Covariant return type change detected: java.nio.Buffer java.nio.Char
Buffer.position(int) has been changed to java.nio.CharBuffer java.nio.CharBuffer.position(int)
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\input\TeeReader.java:158: Covariant return type change detected: java.nio.Buffer java.nio.Char
Buffer.limit(int) has been changed to java.nio.CharBuffer java.nio.CharBuffer.limit(int)
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\input\TeeReader.java:162: Covariant return type change detected: java.nio.Buffer java.nio.Char
Buffer.position(int) has been changed to java.nio.CharBuffer java.nio.CharBuffer.position(int)
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\input\TeeReader.java:162: Covariant return type change detected: java.nio.Buffer java.nio.Char
Buffer.limit(int) has been changed to java.nio.CharBuffer java.nio.CharBuffer.limit(int)
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\input\TeeReader.java:162: Covariant return type change detected: java.nio.Buffer java.nio.Char
Buffer.position(int) has been changed to java.nio.CharBuffer java.nio.CharBuffer.position(int)
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\input\TeeReader.java:162: Covariant return type change detected: java.nio.Buffer java.nio.Char
Buffer.limit(int) has been changed to java.nio.CharBuffer java.nio.CharBuffer.limit(int)
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\input\ReaderInputStream.java:125: Covariant return type change detected: java.nio.Buffer java.
nio.CharBuffer.flip() has been changed to java.nio.CharBuffer java.nio.CharBuffer.flip()
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\input\ReaderInputStream.java:127: Covariant return type change detected: java.nio.Buffer java.
nio.ByteBuffer.flip() has been changed to java.nio.ByteBuffer java.nio.ByteBuffer.flip()
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\input\ReaderInputStream.java:207: Covariant return type change detected: java.nio.Buffer java.
nio.CharBuffer.position(int) has been changed to java.nio.CharBuffer java.nio.CharBuffer.position(int)
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\input\ReaderInputStream.java:209: Covariant return type change detected: java.nio.Buffer java.
nio.CharBuffer.flip() has been changed to java.nio.CharBuffer java.nio.CharBuffer.flip()
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\input\ReaderInputStream.java:213: Covariant return type change detected: java.nio.Buffer java.
nio.ByteBuffer.flip() has been changed to java.nio.ByteBuffer java.nio.ByteBuffer.flip()
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\input\CharSequenceInputStream.java:74: Covariant return type change detected: java.nio.Buffer
java.nio.ByteBuffer.flip() has been changed to java.nio.ByteBuffer java.nio.ByteBuffer.flip()
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\input\CharSequenceInputStream.java:128: Covariant return type change detected: java.nio.Buffer
 java.nio.ByteBuffer.flip() has been changed to java.nio.ByteBuffer java.nio.ByteBuffer.flip()
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\input\CharSequenceInputStream.java:222: Covariant return type change detected: java.nio.Buffer
 java.nio.CharBuffer.mark() has been changed to java.nio.CharBuffer java.nio.CharBuffer.mark()
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\input\CharSequenceInputStream.java:223: Covariant return type change detected: java.nio.Buffer
 java.nio.ByteBuffer.mark() has been changed to java.nio.ByteBuffer java.nio.ByteBuffer.mark()
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\input\CharSequenceInputStream.java:245: Covariant return type change detected: java.nio.Buffer
 java.nio.CharBuffer.rewind() has been changed to java.nio.CharBuffer java.nio.CharBuffer.rewind()
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\input\CharSequenceInputStream.java:246: Covariant return type change detected: java.nio.Buffer
 java.nio.ByteBuffer.rewind() has been changed to java.nio.ByteBuffer java.nio.ByteBuffer.rewind()
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\input\CharSequenceInputStream.java:247: Covariant return type change detected: java.nio.Buffer
 java.nio.ByteBuffer.limit(int) has been changed to java.nio.ByteBuffer java.nio.ByteBuffer.limit(int)
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\input\CharSequenceInputStream.java:249: Covariant return type change detected: java.nio.Buffer
 java.nio.ByteBuffer.rewind() has been changed to java.nio.ByteBuffer java.nio.ByteBuffer.rewind()
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\input\CharSequenceInputStream.java:250: Covariant return type change detected: java.nio.Buffer
 java.nio.ByteBuffer.limit(int) has been changed to java.nio.ByteBuffer java.nio.ByteBuffer.limit(int)
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\input\CharSequenceInputStream.java:258: Covariant return type change detected: java.nio.Buffer
 java.nio.ByteBuffer.position(int) has been changed to java.nio.ByteBuffer java.nio.ByteBuffer.position(int)
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\output\WriterOutputStream.java:283: Covariant return type change detected: java.nio.Buffer jav
a.nio.ByteBuffer.flip() has been changed to java.nio.ByteBuffer java.nio.ByteBuffer.flip()
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\output\WriterOutputStream.java:309: Covariant return type change detected: java.nio.Buffer jav
a.nio.CharBuffer.rewind() has been changed to java.nio.CharBuffer java.nio.CharBuffer.rewind()
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\output\WriterOutputStream.java:331: Covariant return type change detected: java.nio.Buffer jav
a.nio.ByteBuffer.flip() has been changed to java.nio.ByteBuffer java.nio.ByteBuffer.flip()
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\output\WriterOutputStream.java:340: Covariant return type change detected: java.nio.Buffer jav
a.nio.CharBuffer.rewind() has been changed to java.nio.CharBuffer java.nio.CharBuffer.rewind()
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\IOUtils.java:987: Covariant return type change detected: java.nio.Buffer java.nio.CharBuffer.f
lip() has been changed to java.nio.CharBuffer java.nio.CharBuffer.flip()
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\IOUtils.java:2008: Covariant return type change detected: java.nio.Buffer java.nio.ByteBuffer.
position(int) has been changed to java.nio.ByteBuffer java.nio.ByteBuffer.position(int)
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\IOUtils.java:2009: Covariant return type change detected: java.nio.Buffer java.nio.ByteBuffer.
limit(int) has been changed to java.nio.ByteBuffer java.nio.ByteBuffer.limit(int)
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\FileUtils.java:1094: Covariant return type change detected: java.nio.Buffer java.nio.ByteBuffe
r.flip() has been changed to java.nio.ByteBuffer java.nio.ByteBuffer.flip()
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\FileUtils.java:1096: Covariant return type change detected: java.nio.Buffer java.nio.ByteBuffe
r.clear() has been changed to java.nio.ByteBuffer java.nio.ByteBuffer.clear()
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\FileUtils.java:1094: Covariant return type change detected: java.nio.Buffer java.nio.ByteBuffe
r.flip() has been changed to java.nio.ByteBuffer java.nio.ByteBuffer.flip()
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\FileUtils.java:1096: Covariant return type change detected: java.nio.Buffer java.nio.ByteBuffe
r.clear() has been changed to java.nio.ByteBuffer java.nio.ByteBuffer.clear()
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\FileUtils.java:1094: Covariant return type change detected: java.nio.Buffer java.nio.ByteBuffe
r.flip() has been changed to java.nio.ByteBuffer java.nio.ByteBuffer.flip()
[INFO] D:\workspace\commons-io\src\main\java\org\apache\commons\io\FileUtils.java:1096: Covariant return type change detected: java.nio.Buffer java.nio.ByteBuffe
r.clear() has been changed to java.nio.ByteBuffer java.nio.ByteBuffer.clear()
[INFO]
[INFO] --- maven-resources-plugin:3.1.0:testResources (default-testResources) @ commons-io ---
[INFO] Using 'iso-8859-1' encoding to copy filtered resources.
[INFO] Copying 45 resources
[INFO] Copying 2 resources to META-INF
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ commons-io ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 158 source files to D:\workspace\commons-io\target\test-classes
[INFO] /D:/workspace/commons-io/src/test/java/org/apache/commons/io/output/FileWriterWithEncodingTest.java: Some input files use or override a deprecated API.
[INFO] /D:/workspace/commons-io/src/test/java/org/apache/commons/io/output/FileWriterWithEncodingTest.java: Recompile with -Xlint:deprecation for details.
[INFO]
[INFO] --- jacoco-maven-plugin:0.8.5:prepare-agent (prepare-agent) @ commons-io ---
[INFO] argLine set to -javaagent:C:\\Users\\xenoa\\.m2\\repository\\org\\jacoco\\org.jacoco.agent\\0.8.5\\org.jacoco.agent-0.8.5-runtime.jar=destfile=D:\\workspa
ce\\commons-io\\target\\jacoco.exec
[INFO]
[INFO] --- maven-surefire-plugin:2.22.2:test (default-test) @ commons-io ---
[INFO] Tests are skipped.
[INFO]
[INFO] --- exec-maven-plugin:1.6.0:exec (benchmark) @ commons-io ---
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.openjdk.jmh.util.Utils (file:/C:/Users/xenoa/.m2/repository/org/openjdk/jmh/jmh-core/1.21/jmh-core-1.21.jar) to field j
ava.io.PrintStream.charOut
WARNING: Please consider reporting this to the maintainers of org.openjdk.jmh.util.Utils
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
# JMH version: 1.21
# VM version: JDK 13.0.2, OpenJDK 64-Bit Server VM, 13.0.2+8
# VM invoker: C:\jdk-13.0.2+8\bin\java.exe
# VM options: <none>
# Warmup: 5 iterations, 10 s each
# Measurement: 5 iterations, 10 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Average time, time/op
# Benchmark: org.apache.commons.io.performance.IOUtilsContentEqualsPerformanceTest.testContentEqualsForFileNew

# Run progress: 0.00% complete, ETA 00:33:20
# Fork: 1 of 5
# Warmup Iteration   1: 8403699.664 ns/op
# Warmup Iteration   2: 8342097.081 ns/op
# Warmup Iteration   3: 7431033.061 ns/op
# Warmup Iteration   4: 7714089.746 ns/op
# Warmup Iteration   5: 7338344.241 ns/op
Iteration   1: 7459707.308 ns/op
Iteration   2: 8792593.849 ns/op
Iteration   3: 10726891.104 ns/op
Iteration   4: 8550254.786 ns/op
Iteration   5: 8001410.312 ns/op

# Run progress: 5.00% complete, ETA 00:31:55
# Fork: 2 of 5
# Warmup Iteration   1: 7848885.804 ns/op
# Warmup Iteration   2: 7489775.075 ns/op
# Warmup Iteration   3: 7328874.652 ns/op
# Warmup Iteration   4: 7308097.663 ns/op
# Warmup Iteration   5: 7298969.001 ns/op
Iteration   1: 7347818.649 ns/op
Iteration   2: 7251497.464 ns/op
Iteration   3: 7366967.231 ns/op
Iteration   4: 7420473.516 ns/op
Iteration   5: 7517702.630 ns/op

# Run progress: 10.00% complete, ETA 00:30:14
# Fork: 3 of 5
# Warmup Iteration   1: 7403000.592 ns/op
# Warmup Iteration   2: 7237561.577 ns/op
# Warmup Iteration   3: 7328035.212 ns/op
# Warmup Iteration   4: 7310369.686 ns/op
# Warmup Iteration   5: 7258066.255 ns/op
Iteration   1: 7387172.526 ns/op
Iteration   2: 7278674.400 ns/op
Iteration   3: 7307894.887 ns/op
Iteration   4: 7363340.103 ns/op
Iteration   5: 7241780.811 ns/op

# Run progress: 15.00% complete, ETA 00:28:33
# Fork: 4 of 5
# Warmup Iteration   1: 7549794.264 ns/op
# Warmup Iteration   2: 7209186.671 ns/op
# Warmup Iteration   3: 7680527.859 ns/op
# Warmup Iteration   4: 7870276.336 ns/op
# Warmup Iteration   5: 8008019.376 ns/op
Iteration   1: 7868122.956 ns/op
Iteration   2: 8014526.603 ns/op
Iteration   3: 7610742.998 ns/op
Iteration   4: 7339908.804 ns/op
Iteration   5: 7466605.970 ns/op

# Run progress: 20.00% complete, ETA 00:26:52
# Fork: 5 of 5
# Warmup Iteration   1: 8062262.933 ns/op
# Warmup Iteration   2: 7888885.647 ns/op
# Warmup Iteration   3: 8092374.353 ns/op
# Warmup Iteration   4: 7535815.813 ns/op
# Warmup Iteration   5: 8376873.032 ns/op
Iteration   1: 7641931.603 ns/op
Iteration   2: 8134969.268 ns/op
Iteration   3: 8823474.603 ns/op
Iteration   4: 9548556.489 ns/op
Iteration   5: 8888150.622 ns/op


Result "org.apache.commons.io.performance.IOUtilsContentEqualsPerformanceTest.testContentEqualsForFileNew":
  7934046.780 ?99.9%) 644395.868 ns/op [Average]

  (min, avg, max) = (7241780.811, 7934046.780, 10726891.104), stdev = 860250.047
  CI (99.9%): [7289650.912, 8578442.648] (assumes normal distribution)


# JMH version: 1.21
# VM version: JDK 13.0.2, OpenJDK 64-Bit Server VM, 13.0.2+8
# VM invoker: C:\jdk-13.0.2+8\bin\java.exe
# VM options: <none>
# Warmup: 5 iterations, 10 s each
# Measurement: 5 iterations, 10 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Average time, time/op
# Benchmark: org.apache.commons.io.performance.IOUtilsContentEqualsPerformanceTest.testContentEqualsNew2

# Run progress: 25.00% complete, ETA 00:25:12
# Fork: 1 of 5
# Warmup Iteration   1: 427439412.500 ns/op
# Warmup Iteration   2: 411941108.000 ns/op
# Warmup Iteration   3: 415405856.000 ns/op
# Warmup Iteration   4: 408246064.000 ns/op
# Warmup Iteration   5: 381986007.407 ns/op
Iteration   1: 372559803.704 ns/op
Iteration   2: 372221244.444 ns/op
Iteration   3: 394561276.923 ns/op
Iteration   4: 410318660.000 ns/op
Iteration   5: 417270562.500 ns/op

# Run progress: 30.00% complete, ETA 00:23:36
# Fork: 2 of 5
# Warmup Iteration   1: 385519323.077 ns/op
# Warmup Iteration   2: 341417310.000 ns/op
# Warmup Iteration   3: 337620636.667 ns/op
# Warmup Iteration   4: 337741280.000 ns/op
# Warmup Iteration   5: 322947274.194 ns/op
Iteration   1: 334579670.000 ns/op
Iteration   2: 324313664.516 ns/op
Iteration   3: 349864203.448 ns/op
Iteration   4: 345000172.414 ns/op
Iteration   5: 338797430.000 ns/op

# Run progress: 35.00% complete, ETA 00:21:56
# Fork: 3 of 5
# Warmup Iteration   1: 424080325.000 ns/op
# Warmup Iteration   2: 409074288.000 ns/op
# Warmup Iteration   3: 397216476.923 ns/op
# Warmup Iteration   4: 379384881.481 ns/op
# Warmup Iteration   5: 406599224.000 ns/op
Iteration   1: 344006786.667 ns/op
Iteration   2: 318393962.500 ns/op
Iteration   3: 326383164.516 ns/op
Iteration   4: 326728512.903 ns/op
Iteration   5: 339791536.667 ns/op

# Run progress: 40.00% complete, ETA 00:20:17
# Fork: 4 of 5
# Warmup Iteration   1: 359791750.000 ns/op
# Warmup Iteration   2: 344011470.000 ns/op
# Warmup Iteration   3: 317443868.750 ns/op
# Warmup Iteration   4: 366668921.429 ns/op
# Warmup Iteration   5: 340980226.667 ns/op
Iteration   1: 362224464.286 ns/op
Iteration   2: 329631980.645 ns/op
Iteration   3: 328959990.323 ns/op
Iteration   4: 331093680.645 ns/op
Iteration   5: 328042438.710 ns/op

# Run progress: 45.00% complete, ETA 00:18:37
# Fork: 5 of 5
# Warmup Iteration   1: 328533070.968 ns/op
# Warmup Iteration   2: 321877478.125 ns/op
# Warmup Iteration   3: 315723571.875 ns/op
# Warmup Iteration   4: 323838003.226 ns/op
# Warmup Iteration   5: 325582848.387 ns/op
Iteration   1: 322872964.516 ns/op
Iteration   2: 320972165.625 ns/op
Iteration   3: 322146753.125 ns/op
Iteration   4: 320983556.250 ns/op
Iteration   5: 332471216.129 ns/op


Result "org.apache.commons.io.performance.IOUtilsContentEqualsPerformanceTest.testContentEqualsNew2":
  344567594.458 ?99.9%) 21104733.591 ns/op [Average]

  (min, avg, max) = (318393962.500, 344567594.458, 417270562.500), stdev = 28174215.532
  CI (99.9%): [323462860.868, 365672328.049] (assumes normal distribution)


# JMH version: 1.21
# VM version: JDK 13.0.2, OpenJDK 64-Bit Server VM, 13.0.2+8
# VM invoker: C:\jdk-13.0.2+8\bin\java.exe
# VM options: <none>
# Warmup: 5 iterations, 10 s each
# Measurement: 5 iterations, 10 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Average time, time/op
# Benchmark: org.apache.commons.io.performance.IOUtilsContentEqualsPerformanceTest.testContentEqualsOld

# Run progress: 50.00% complete, ETA 00:16:57
# Fork: 1 of 5
# Warmup Iteration   1: 8040772.910 ns/op
# Warmup Iteration   2: 7850546.468 ns/op
# Warmup Iteration   3: 8366507.191 ns/op
# Warmup Iteration   4: 8919272.193 ns/op
# Warmup Iteration   5: 8934492.411 ns/op
Iteration   1: 9849140.059 ns/op
Iteration   2: 10280016.496 ns/op
Iteration   3: 9377572.540 ns/op
Iteration   4: 8634857.550 ns/op
Iteration   5: 8796502.111 ns/op

# Run progress: 55.00% complete, ETA 00:15:14
# Fork: 2 of 5
# Warmup Iteration   1: 9196890.441 ns/op
# Warmup Iteration   2: 8651530.769 ns/op
# Warmup Iteration   3: 9130613.504 ns/op
# Warmup Iteration   4: 9528571.075 ns/op
# Warmup Iteration   5: 8603469.046 ns/op
Iteration   1: 8649056.612 ns/op
Iteration   2: 8740562.707 ns/op
Iteration   3: 8636735.807 ns/op
Iteration   4: 8658414.545 ns/op
Iteration   5: 9077745.554 ns/op

# Run progress: 60.00% complete, ETA 00:13:32
# Fork: 3 of 5
# Warmup Iteration   1: 9210640.074 ns/op
# Warmup Iteration   2: 7950668.124 ns/op
# Warmup Iteration   3: 8049352.132 ns/op
# Warmup Iteration   4: 7906520.949 ns/op
# Warmup Iteration   5: 8193835.545 ns/op
Iteration   1: 7833574.706 ns/op
Iteration   2: 8025837.640 ns/op
Iteration   3: 8621776.034 ns/op
Iteration   4: 8516147.915 ns/op
Iteration   5: 8379908.710 ns/op

# Run progress: 65.00% complete, ETA 00:11:50
# Fork: 4 of 5
# Warmup Iteration   1: 8810415.141 ns/op
# Warmup Iteration   2: 8794569.859 ns/op
# Warmup Iteration   3: 8730751.745 ns/op
# Warmup Iteration   4: 8563348.202 ns/op
# Warmup Iteration   5: 8946487.757 ns/op
Iteration   1: 8798953.725 ns/op
Iteration   2: 9077297.461 ns/op
Iteration   3: 9203544.250 ns/op
Iteration   4: 10801144.492 ns/op
Iteration   5: 10137045.694 ns/op

# Run progress: 70.00% complete, ETA 00:10:09
# Fork: 5 of 5
# Warmup Iteration   1: 10034710.933 ns/op
# Warmup Iteration   2: 7852066.954 ns/op
# Warmup Iteration   3: 8036246.265 ns/op
# Warmup Iteration   4: 8208804.184 ns/op
# Warmup Iteration   5: 8919215.241 ns/op
Iteration   1: 7703625.019 ns/op
Iteration   2: 8173784.069 ns/op
Iteration   3: 8476930.000 ns/op
Iteration   4: 9254641.073 ns/op
Iteration   5: 8732920.419 ns/op


Result "org.apache.commons.io.performance.IOUtilsContentEqualsPerformanceTest.testContentEqualsOld":
  8897509.408 ?99.9%) 558227.023 ns/op [Average]

  (min, avg, max) = (7703625.019, 8897509.408, 10801144.492), stdev = 745217.105
  CI (99.9%): [8339282.385, 9455736.431] (assumes normal distribution)


# JMH version: 1.21
# VM version: JDK 13.0.2, OpenJDK 64-Bit Server VM, 13.0.2+8
# VM invoker: C:\jdk-13.0.2+8\bin\java.exe
# VM options: <none>
# Warmup: 5 iterations, 10 s each
# Measurement: 5 iterations, 10 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Average time, time/op
# Benchmark: org.apache.commons.io.performance.IOUtilsContentEqualsPerformanceTest.testContentEqualsOld2

# Run progress: 75.00% complete, ETA 00:08:27
# Fork: 1 of 5
# Warmup Iteration   1: 2274597420.000 ns/op
# Warmup Iteration   2: 2161414140.000 ns/op
# Warmup Iteration   3: 2060648900.000 ns/op
# Warmup Iteration   4: 2034553880.000 ns/op
# Warmup Iteration   5: 2036716060.000 ns/op
Iteration   1: 2039811500.000 ns/op
Iteration   2: 2029332780.000 ns/op
Iteration   3: 2048828760.000 ns/op
Iteration   4: 2167898680.000 ns/op
Iteration   5: 2375598240.000 ns/op

# Run progress: 80.00% complete, ETA 00:06:47
# Fork: 2 of 5
# Warmup Iteration   1: 2302730460.000 ns/op
# Warmup Iteration   2: 2169550200.000 ns/op
# Warmup Iteration   3: 2183069220.000 ns/op
# Warmup Iteration   4: 2219912760.000 ns/op
# Warmup Iteration   5: 2276130160.000 ns/op
Iteration   1: 2256782140.000 ns/op
Iteration   2: 2212519940.000 ns/op
Iteration   3: 2194957540.000 ns/op
Iteration   4: 2139474860.000 ns/op
Iteration   5: 2239168680.000 ns/op

# Run progress: 85.00% complete, ETA 00:05:07
# Fork: 3 of 5
# Warmup Iteration   1: 2871005625.000 ns/op
# Warmup Iteration   2: 2234621780.000 ns/op
# Warmup Iteration   3: 2057113240.000 ns/op
# Warmup Iteration   4: 2106691240.000 ns/op
# Warmup Iteration   5: 2239427440.000 ns/op
Iteration   1: 2221194720.000 ns/op
Iteration   2: 2252754040.000 ns/op
Iteration   3: 2362948520.000 ns/op
Iteration   4: 2233297260.000 ns/op
Iteration   5: 2289872180.000 ns/op

# Run progress: 90.00% complete, ETA 00:03:25
# Fork: 4 of 5
# Warmup Iteration   1: 2316297000.000 ns/op
# Warmup Iteration   2: 2186447840.000 ns/op
# Warmup Iteration   3: 2186496100.000 ns/op
# Warmup Iteration   4: 2210486500.000 ns/op
# Warmup Iteration   5: 2248586640.000 ns/op
Iteration   1: 2228412480.000 ns/op
Iteration   2: 2293236620.000 ns/op
Iteration   3: 2300933160.000 ns/op
Iteration   4: 2050526440.000 ns/op
Iteration   5: 2103876620.000 ns/op

# Run progress: 95.00% complete, ETA 00:01:43
# Fork: 5 of 5
# Warmup Iteration   1: 2231988940.000 ns/op
# Warmup Iteration   2: 2132075180.000 ns/op
# Warmup Iteration   3: 2107424340.000 ns/op
# Warmup Iteration   4: 2244625860.000 ns/op
# Warmup Iteration   5: 2212587240.000 ns/op
Iteration   1: 2358689240.000 ns/op
Iteration   2: 2360920240.000 ns/op
Iteration   3: 2304193360.000 ns/op
Iteration   4: 2120541520.000 ns/op
Iteration   5: 2225049120.000 ns/op


Result "org.apache.commons.io.performance.IOUtilsContentEqualsPerformanceTest.testContentEqualsOld2":
  2216432745.600 ?99.9%) 79521556.878 ns/op [Average]

  (min, avg, max) = (2029332780.000, 2216432745.600, 2375598240.000), stdev = 106159003.301
  CI (99.9%): [2136911188.722, 2295954302.478] (assumes normal distribution)


# Run complete. Total time: 00:34:37

REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on
why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial
experiments, perform baseline and negative tests that provide experimental control, make sure
the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts.
Do not assume the numbers tell you what you want them to tell.

Benchmark                                                        Mode  Cnt           Score          Error  Units
IOUtilsContentEqualsPerformanceTest.testContentEqualsForFileNew  avgt   25     7934046.780 ?  644395.868  ns/op

IOUtilsContentEqualsPerformanceTest.testContentEqualsNew2        avgt   25   344567594.458 ?21104733.591  ns/op

IOUtilsContentEqualsPerformanceTest.testContentEqualsOld         avgt   25     8897509.408 ?  558227.023  ns/op

IOUtilsContentEqualsPerformanceTest.testContentEqualsOld2        avgt   25  2216432745.600 ?79521556.878  ns/op


Benchmark result is saved to target/jmh-result.org.apache.json
[INFO]
[INFO] --- maven-jar-plugin:3.2.0:jar (default-jar) @ commons-io ---
[INFO] Building jar: D:\workspace\commons-io\target\commons-io-2.7.1-SNAPSHOT.jar
[INFO]
[INFO] --- maven-site-plugin:3.8.2:attach-descriptor (attach-descriptor) @ commons-io ---
[INFO] Skipping because packaging 'jar' is not pom.
[INFO]
[INFO] --- maven-jar-plugin:3.2.0:test-jar (default) @ commons-io ---
[INFO] Building jar: D:\workspace\commons-io\target\commons-io-2.7.1-SNAPSHOT-tests.jar
[INFO]
[INFO] --- maven-source-plugin:3.2.0:jar-no-fork (create-source-jar) @ commons-io ---
[INFO] Building jar: D:\workspace\commons-io\target\commons-io-2.7.1-SNAPSHOT-sources.jar
[INFO]
[INFO] --- maven-source-plugin:3.2.0:test-jar-no-fork (create-source-jar) @ commons-io ---
[INFO] Building jar: D:\workspace\commons-io\target\commons-io-2.7.1-SNAPSHOT-test-sources.jar
[INFO]
[INFO] --- jacoco-maven-plugin:0.8.5:check (check) @ commons-io ---
[INFO] Skipping JaCoCo execution due to missing execution data file:D:\workspace\commons-io\target\jacoco.exec
[INFO]
[INFO] --- apache-rat-plugin:0.13:check (default-cli) @ commons-io ---
[INFO] Enabled default license matchers.
[INFO] Will parse SCM ignores for exclusions...
[INFO] Parsing exclusions from D:\workspace\commons-io\.gitignore
[INFO] Finished adding exclusions from SCM ignore files.
[INFO] 73 implicit excludes (use -debug for more details).
[INFO] 12 explicit excludes (use -debug for more details).
[INFO] 373 resources included (use -debug for more details)
[INFO] Rat check: Summary over all files. Unapproved: 0, unknown: 0, generated: 0, approved: 364 licenses.
[INFO]
[INFO] >>> clirr-maven-plugin:2.8:check (default-cli) > compile @ commons-io >>>
[INFO]
[INFO] --- maven-enforcer-plugin:3.0.0-M2:enforce (enforce-maven-version) @ commons-io ---
[INFO]
[INFO] --- maven-enforcer-plugin:3.0.0-M2:enforce (enforce-maven-3) @ commons-io ---
[INFO]
[INFO] --- apache-rat-plugin:0.13:check (rat-check) @ commons-io ---
[INFO] Enabled default license matchers.
[INFO] Will parse SCM ignores for exclusions...
[INFO] Parsing exclusions from D:\workspace\commons-io\.gitignore
[INFO] Finished adding exclusions from SCM ignore files.
[INFO] 73 implicit excludes (use -debug for more details).
[INFO] 12 explicit excludes (use -debug for more details).
[INFO] 373 resources included (use -debug for more details)
[INFO] Rat check: Summary over all files. Unapproved: 0, unknown: 0, generated: 0, approved: 364 licenses.
[INFO]
[INFO] --- build-helper-maven-plugin:3.0.0:parse-version (parse-version) @ commons-io ---
[INFO]
[INFO] --- maven-antrun-plugin:1.8:run (javadoc.resources) @ commons-io ---
[INFO] Executing tasks

main:
[INFO] Executed tasks
[INFO]
[INFO] --- maven-remote-resources-plugin:1.5:process (process-resource-bundles) @ commons-io ---
[INFO]
[INFO] --- buildnumber-maven-plugin:1.4:create (default) @ commons-io ---
[INFO] Executing: cmd.exe /X /C "git rev-parse --verify HEAD"
[INFO] Working directory: D:\workspace\commons-io
[INFO] Storing buildNumber: 73dc0ff3e6d79ab88f1ed0d253d52cb6da0dffa5 at timestamp: 1591036535724
[INFO] Storing buildScmBranch: refine_contentEquals
[INFO]
[INFO] --- maven-resources-plugin:3.1.0:resources (default-resources) @ commons-io ---
[INFO] Using 'iso-8859-1' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory D:\workspace\commons-io\src\main\resources
[INFO] Copying 2 resources to META-INF
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ commons-io ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 158 source files to D:\workspace\commons-io\target\classes
[INFO] /D:/workspace/commons-io/src/main/java/org/apache/commons/io/input/ClassLoaderObjectInputStream.java: Some input files use or override a deprecated API.
[INFO] /D:/workspace/commons-io/src/main/java/org/apache/commons/io/input/ClassLoaderObjectInputStream.java: Recompile with -Xlint:deprecation for details.
[INFO] /D:/workspace/commons-io/src/main/java/org/apache/commons/io/IOExceptionList.java: D:\workspace\commons-io\src\main\java\org\apache\commons\io\IOException
List.java uses unchecked or unsafe operations.
[INFO] /D:/workspace/commons-io/src/main/java/org/apache/commons/io/IOExceptionList.java: Recompile with -Xlint:unchecked for details.
[INFO]
[INFO] <<< clirr-maven-plugin:2.8:check (default-cli) < compile @ commons-io <<<
[INFO]
[INFO]
[INFO] --- clirr-maven-plugin:2.8:check (default-cli) @ commons-io ---
[INFO] Comparing to version: 2.7
[INFO] Succeeded with 0 errors; 0 warnings; and 0 other changes.
[INFO]
[INFO] --- maven-checkstyle-plugin:3.1.0:check (default-cli) @ commons-io ---
[INFO]
[INFO] >>> maven-javadoc-plugin:3.1.1:javadoc (default-cli) > generate-sources @ commons-io >>>
[INFO]
[INFO] --- maven-enforcer-plugin:3.0.0-M2:enforce (enforce-maven-version) @ commons-io ---
[INFO]
[INFO] --- maven-enforcer-plugin:3.0.0-M2:enforce (enforce-maven-3) @ commons-io ---
[INFO]
[INFO] --- apache-rat-plugin:0.13:check (rat-check) @ commons-io ---
[INFO] Enabled default license matchers.
[INFO] Will parse SCM ignores for exclusions...
[INFO] Parsing exclusions from D:\workspace\commons-io\.gitignore
[INFO] Finished adding exclusions from SCM ignore files.
[INFO] 73 implicit excludes (use -debug for more details).
[INFO] 12 explicit excludes (use -debug for more details).
[INFO] 373 resources included (use -debug for more details)
[INFO] Rat check: Summary over all files. Unapproved: 0, unknown: 0, generated: 0, approved: 364 licenses.
[INFO]
[INFO] --- build-helper-maven-plugin:3.0.0:parse-version (parse-version) @ commons-io ---
[INFO]
[INFO] --- maven-antrun-plugin:1.8:run (javadoc.resources) @ commons-io ---
[INFO] Executing tasks

main:
[INFO] Executed tasks
[INFO]
[INFO] <<< maven-javadoc-plugin:3.1.1:javadoc (default-cli) < generate-sources @ commons-io <<<
[INFO]
[INFO]
[INFO] --- maven-javadoc-plugin:3.1.1:javadoc (default-cli) @ commons-io ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  35:31 min
[INFO] Finished at: 2020-06-02T02:35:59+08:00
[INFO] ------------------------------------------------------------------------

XenoAmess avatar Jun 01 '20 18:06 XenoAmess

result json:

[
    {
        "jmhVersion" : "1.21",
        "benchmark" : "org.apache.commons.io.performance.IOUtilsContentEqualsPerformanceTest.testContentEqualsForFileNew",
        "mode" : "avgt",
        "threads" : 1,
        "forks" : 5,
        "jvm" : "C:\\jdk-13.0.2+8\\bin\\java.exe",
        "jvmArgs" : [
        ],
        "jdkVersion" : "13.0.2",
        "vmName" : "OpenJDK 64-Bit Server VM",
        "vmVersion" : "13.0.2+8",
        "warmupIterations" : 5,
        "warmupTime" : "10 s",
        "warmupBatchSize" : 1,
        "measurementIterations" : 5,
        "measurementTime" : "10 s",
        "measurementBatchSize" : 1,
        "primaryMetric" : {
            "score" : 7934046.779660092,
            "scoreError" : 644395.8679898068,
            "scoreConfidence" : [
                7289650.911670285,
                8578442.6476499
            ],
            "scorePercentiles" : {
                "0.0" : 7241780.811006517,
                "50.0" : 7517702.629601804,
                "90.0" : 9152312.968421623,
                "95.0" : 1.0373390719340876E7,
                "99.0" : 1.0726891103965702E7,
                "99.9" : 1.0726891103965702E7,
                "99.99" : 1.0726891103965702E7,
                "99.999" : 1.0726891103965702E7,
                "99.9999" : 1.0726891103965702E7,
                "100.0" : 1.0726891103965702E7
            },
            "scoreUnit" : "ns/op",
            "rawData" : [
                [
                    7459707.30797912,
                    8792593.848857645,
                    1.0726891103965702E7,
                    8550254.786324786,
                    8001410.311750599
                ],
                [
                    7347818.649045521,
                    7251497.463768116,
                    7366967.231222386,
                    7420473.516320474,
                    7517702.629601804
                ],
                [
                    7387172.525849335,
                    7278674.4,
                    7307894.88677867,
                    7363340.103016924,
                    7241780.811006517
                ],
                [
                    7868122.955974842,
                    8014526.602564103,
                    7610742.99847793,
                    7339908.804108584,
                    7466605.9701492535
                ],
                [
                    7641931.603053435,
                    8134969.268292683,
                    8823474.603174603,
                    9548556.488549618,
                    8888150.621669628
                ]
            ]
        },
        "secondaryMetrics" : {
        }
    },
    {
        "jmhVersion" : "1.21",
        "benchmark" : "org.apache.commons.io.performance.IOUtilsContentEqualsPerformanceTest.testContentEqualsNew2",
        "mode" : "avgt",
        "threads" : 1,
        "forks" : 5,
        "jvm" : "C:\\jdk-13.0.2+8\\bin\\java.exe",
        "jvmArgs" : [
        ],
        "jdkVersion" : "13.0.2",
        "vmName" : "OpenJDK 64-Bit Server VM",
        "vmVersion" : "13.0.2+8",
        "warmupIterations" : 5,
        "warmupTime" : "10 s",
        "warmupBatchSize" : 1,
        "measurementIterations" : 5,
        "measurementTime" : "10 s",
        "measurementBatchSize" : 1,
        "primaryMetric" : {
            "score" : 3.4456759445822275E8,
            "scoreError" : 2.110473359059532E7,
            "scoreConfidence" : [
                3.2346286086762744E8,
                3.6567232804881805E8
            ],
            "scorePercentiles" : {
                "0.0" : 3.183939625E8,
                "50.0" : 3.3247121612903225E8,
                "90.0" : 4.0086423015384614E8,
                "95.0" : 4.1518499175E8,
                "99.0" : 4.172705625E8,
                "99.9" : 4.172705625E8,
                "99.99" : 4.172705625E8,
                "99.999" : 4.172705625E8,
                "99.9999" : 4.172705625E8,
                "100.0" : 4.172705625E8
            },
            "scoreUnit" : "ns/op",
            "rawData" : [
                [
                    3.725598037037037E8,
                    3.722212444444444E8,
                    3.945612769230769E8,
                    4.1031866E8,
                    4.172705625E8
                ],
                [
                    3.3457967E8,
                    3.24313664516129E8,
                    3.4986420344827586E8,
                    3.450001724137931E8,
                    3.3879743E8
                ],
                [
                    3.440067866666667E8,
                    3.183939625E8,
                    3.26383164516129E8,
                    3.267285129032258E8,
                    3.397915366666667E8
                ],
                [
                    3.6222446428571427E8,
                    3.296319806451613E8,
                    3.2895999032258064E8,
                    3.310936806451613E8,
                    3.280424387096774E8
                ],
                [
                    3.22872964516129E8,
                    3.20972165625E8,
                    3.22146753125E8,
                    3.2098355625E8,
                    3.3247121612903225E8
                ]
            ]
        },
        "secondaryMetrics" : {
        }
    },
    {
        "jmhVersion" : "1.21",
        "benchmark" : "org.apache.commons.io.performance.IOUtilsContentEqualsPerformanceTest.testContentEqualsOld",
        "mode" : "avgt",
        "threads" : 1,
        "forks" : 5,
        "jvm" : "C:\\jdk-13.0.2+8\\bin\\java.exe",
        "jvmArgs" : [
        ],
        "jdkVersion" : "13.0.2",
        "vmName" : "OpenJDK 64-Bit Server VM",
        "vmVersion" : "13.0.2+8",
        "warmupIterations" : 5,
        "warmupTime" : "10 s",
        "warmupBatchSize" : 1,
        "measurementIterations" : 5,
        "measurementTime" : "10 s",
        "measurementBatchSize" : 1,
        "primaryMetric" : {
            "score" : 8897509.407577794,
            "scoreError" : 558227.0229691897,
            "scoreConfidence" : [
                8339282.384608604,
                9455736.430546984
            ],
            "scorePercentiles" : {
                "0.0" : 7703625.019245573,
                "50.0" : 8732920.418848168,
                "90.0" : 1.019423401477403E7,
                "95.0" : 1.0644806093478914E7,
                "99.0" : 1.0801144492440606E7,
                "99.9" : 1.0801144492440606E7,
                "99.99" : 1.0801144492440606E7,
                "99.999" : 1.0801144492440606E7,
                "99.9999" : 1.0801144492440606E7,
                "100.0" : 1.0801144492440606E7
            },
            "scoreUnit" : "ns/op",
            "rawData" : [
                [
                    9849140.059055118,
                    1.0280016495901639E7,
                    9377572.539831303,
                    8634857.549611734,
                    8796502.110817943
                ],
                [
                    8649056.611927398,
                    8740562.70742358,
                    8636735.806729939,
                    8658414.545454545,
                    9077745.55353902
                ],
                [
                    7833574.706342991,
                    8025837.640449438,
                    8621776.034482758,
                    8516147.914893618,
                    8379908.710217755
                ],
                [
                    8798953.724802805,
                    9077297.46146872,
                    9203544.25022999,
                    1.0801144492440606E7,
                    1.013704569402229E7
                ],
                [
                    7703625.019245573,
                    8173784.068627451,
                    8476930.0,
                    9254641.073080482,
                    8732920.418848168
                ]
            ]
        },
        "secondaryMetrics" : {
        }
    },
    {
        "jmhVersion" : "1.21",
        "benchmark" : "org.apache.commons.io.performance.IOUtilsContentEqualsPerformanceTest.testContentEqualsOld2",
        "mode" : "avgt",
        "threads" : 1,
        "forks" : 5,
        "jvm" : "C:\\jdk-13.0.2+8\\bin\\java.exe",
        "jvmArgs" : [
        ],
        "jdkVersion" : "13.0.2",
        "vmName" : "OpenJDK 64-Bit Server VM",
        "vmVersion" : "13.0.2+8",
        "warmupIterations" : 5,
        "warmupTime" : "10 s",
        "warmupBatchSize" : 1,
        "measurementIterations" : 5,
        "measurementTime" : "10 s",
        "measurementBatchSize" : 1,
        "primaryMetric" : {
            "score" : 2.2164327456E9,
            "scoreError" : 7.952155687779064E7,
            "scoreConfidence" : [
                2.1369111887222092E9,
                2.2959543024777904E9
            ],
            "scorePercentiles" : {
                "0.0" : 2.02933278E9,
                "50.0" : 2.22841248E9,
                "90.0" : 2.361731552E9,
                "95.0" : 2.371803324E9,
                "99.0" : 2.37559824E9,
                "99.9" : 2.37559824E9,
                "99.99" : 2.37559824E9,
                "99.999" : 2.37559824E9,
                "99.9999" : 2.37559824E9,
                "100.0" : 2.37559824E9
            },
            "scoreUnit" : "ns/op",
            "rawData" : [
                [
                    2.0398115E9,
                    2.02933278E9,
                    2.04882876E9,
                    2.16789868E9,
                    2.37559824E9
                ],
                [
                    2.25678214E9,
                    2.21251994E9,
                    2.19495754E9,
                    2.13947486E9,
                    2.23916868E9
                ],
                [
                    2.22119472E9,
                    2.25275404E9,
                    2.36294852E9,
                    2.23329726E9,
                    2.28987218E9
                ],
                [
                    2.22841248E9,
                    2.29323662E9,
                    2.30093316E9,
                    2.05052644E9,
                    2.10387662E9
                ],
                [
                    2.35868924E9,
                    2.36092024E9,
                    2.30419336E9,
                    2.12054152E9,
                    2.22504912E9
                ]
            ]
        },
        "secondaryMetrics" : {
        }
    }
]

XenoAmess avatar Jun 01 '20 18:06 XenoAmess

@garydgregory Hi gary. please find some time for this pr. If this pr make sence, then I'll renew other contentEquals functions in the same class. thx.

XenoAmess avatar Jun 05 '20 15:06 XenoAmess

OK, according to 72H lazy consensus, I think nobody strongly against this change. and I will continue changing codes like this in other IOUtils.contentEquals overloads today.

XenoAmess avatar Jun 08 '20 23:06 XenoAmess

Just FYI, your expectations for 72 hour consensus might be slightly off, it usually applies to certain kinds of votes, not parts of PRs.

garydgregory avatar Jun 09 '20 02:06 garydgregory

Just FYI, your expectations for 72 hour consensus might be slightly off, it usually applies to certain kinds of votes, not parts of PRs.

@garydgregory Oh really... Then I might should delay it... Anyway, I've already finished what I want in this pr for now. Now all the 3 contentEquals functions are remaked. I also added some tests. So if anybody want to review it this might be a good time.

XenoAmess avatar Jun 09 '20 04:06 XenoAmess

The code needs comments. It's not clear what the variables are doing, nor what the algorithm is.

In the case of contentEquals(InputStream...) and contentEquals(Reader ...) it would be enough to comment one and refer the reader to the other for details as they are relatively short and use exactly the same logic AFAICT. I don't suppose there is any way to share the code?

The other method is now enormous, and really ought to be refactored if possible. It certainly needs careful comments to describe the algorithm.

Also what does -1 mean? I assume it is the EOF marker, in which case why not use the EOF constant?

sebbASF avatar Jul 29 '20 10:07 sebbASF

Hi. I added comments for a function, and refined performance test recently. full test at: https://pastebin.ubuntu.com/p/m9PK52gznf/ In short:

Benchmark                                                                   Mode  Cnt           Score           Error  Units
IOUtilsContentEqualsPerformanceTest.testContentEqualsForFileNew             avgt   25     4021167.663 ?    30682.529  ns/op

IOUtilsContentEqualsPerformanceTest.testContentEqualsForFileOld             avgt   25     4396755.117 ?    45747.957  ns/op

IOUtilsContentEqualsPerformanceTest.testContentEqualsForStringNew           avgt   25   464646861.938 ?  8169109.450  ns/op

IOUtilsContentEqualsPerformanceTest.testContentEqualsForStringOld           avgt   25  2895667654.000 ? 77500989.791  ns/op

IOUtilsContentEqualsPerformanceTest.testContentEqualsIgnoreEOLForFileNew    avgt   25     4124001.545 ?    56479.453  ns/op

IOUtilsContentEqualsPerformanceTest.testContentEqualsIgnoreEOLForFileOld    avgt   25     4190892.835 ?    55878.484  ns/op

IOUtilsContentEqualsPerformanceTest.testContentEqualsIgnoreEOLForStringNew  avgt   25  3165287610.267 ?398266582.335  ns/op

IOUtilsContentEqualsPerformanceTest.testContentEqualsIgnoreEOLForStringOld  avgt   25  6108671322.000 ? 68331589.659  ns/op

Considering about FileReader itself is a time coster(and too slow that might hide the contentEquals's runing time), so I mainly use StringReader 's result for showing performance gain. For contentEquals, it is about (2895667654.000/464646861.938) - 100% = 523% faster. For contentEqualsIgnoreEOL, it is (6108671322.000/3165287610.267) - 100% = 92% faster.

XenoAmess avatar Jul 29 '20 11:07 XenoAmess

@sebbASF

The code needs comments. It's not clear what the variables are doing, nor what the algorithm is.

OK, I'm adding comments now.

I don't suppose there is any way to share the code?

Well if we use AspectJ and AOP there might be some solution, but since it be a pure java project, I cannot get any ideas about this...

The other method is now enormous, and really ought to be refactored if possible. It certainly needs careful comments to describe the algorithm.

I've done some comments for the function. Feel free to ask me adding more, if needed.

Also what does -1 mean? I assume it is the EOF marker, in which case why not use the EOF constant?

Yes you are right. I will change it to EOF.

XenoAmess avatar Jul 29 '20 11:07 XenoAmess

It occurs to me that the code is effectively buffering the output from a BufferedReader (or BufferedInputStream). One would expect these classes to be reasonably fast, however the JVM has to do locking and other checks in order to support multi-threading. It has to do this for each read() call.

Rather than implement the buffering directly in the compare methods, it might be better to implement a generic, non-threadsafe buffered reader/stream that can be used in situations such as these. [No need to wrap the original input in a buffered version first]. It would be a non-threadsafe version of BufferedReader/InputStream.

The original code should then work without any change other than to add the filter.

sebbASF avatar Jul 29 '20 15:07 sebbASF

@sebbASF

It occurs to me that the code is effectively buffering the output from a BufferedReader (or BufferedInputStream).

Yes, this is the main trick. For that two not-so-long function, I used another trick to make it even faster by using same checkIndex for two buffers.

One would expect these classes to be reasonably fast, however the JVM has to do locking and other checks in order to support multi-threading. It has to do this for each read() call.

Rather than implement the buffering directly in the compare methods, it might be better to implement a generic, non-threadsafe filter that can be used in situations such as these.

The original code should then work without any change other than to add the filter.

I used the filter idea you mentioned and re-write another implementation, named contentEqualsIgnoreEOLNew2. You can see it in the latest commit. A fast performance test shows that it is SLOWER than my giant function (called contentEqualsIgnoreEOLNew1), but still very much FASTER than the original implementation in commons-io.

And I worried if we really split it out to class, it may become even slower. (still, faster than original, of course.)

But, I do agree with your idea, a non-thread-safe-but-faster-BufferedReader is valuable in many cases. Should we find some time to implement it?

XenoAmess avatar Jul 29 '20 16:07 XenoAmess

will re-run the performance test and see how it can get after 10s warm-up. If the performance lost is not so much, I will recommand contentEqualsIgnoreEOLNew2 as it is really shorter.

XenoAmess avatar Jul 29 '20 16:07 XenoAmess

It looks to me like contentEqualsIgnoreEOLNew2 is using InputReader - I cannot see any buffering?

sebbASF avatar Jul 29 '20 16:07 sebbASF

@sebbASF

It looks to me like contentEqualsIgnoreEOLNew2 is using InputReader - I cannot see any buffering?

it is embeded. I used charArray1 and charArray2 as buffer, and make it a filter-like-check everytime we read some chars, to make sure all "\r\n" become "\n", and all "\r" become "\n" (actually not all, but the basic idea is like this).

XenoAmess avatar Jul 29 '20 16:07 XenoAmess

I see. I would be clearer to use a separate class to implement this.

However the method inputOnlyHaveCRLForEOF uses read() on an unbuffered input class.

Note that IO has a CircularBufferInputStream which may be suitable for at least one of the cases. Should be easy enough to implement the Reader equivalent.

sebbASF avatar Jul 29 '20 17:07 sebbASF

Hi. I just found a bug in contentEqualsIgnoreEOLNew2. Will redo it tomorrow.


Actually will redo it anyway, as I thought it good to split it out to some class structure, rather than repeat two times in the function.

XenoAmess avatar Jul 29 '20 18:07 XenoAmess

Hi. I refined somethings today, and redone performance test recently. full test at: https://pastebin.ubuntu.com/p/sRdCJ9gWCv/ In short:

Benchmark                                                                                  Mode  Cnt           Score           Error  Units
IOUtilsContentEqualsPerformanceTest.testContentEqualsForFileNew                            avgt   25      398196.005 ?     33244.163  ns/op
IOUtilsContentEqualsPerformanceTest.testContentEqualsForFileOld                            avgt   25      431434.178 ?     23966.418  ns/op
IOUtilsContentEqualsPerformanceTest.testContentEqualsForStringNew                          avgt   25   458685306.909 ?  11892533.474  ns/op
IOUtilsContentEqualsPerformanceTest.testContentEqualsForStringOld                          avgt   25  2853863030.000 ? 558816588.555  ns/op
IOUtilsContentEqualsPerformanceTest.testContentEqualsIgnoreEOLForFileNew                   avgt   25      413638.923 ?    130400.817  ns/op
IOUtilsContentEqualsPerformanceTest.testContentEqualsIgnoreEOLForFileNew2                  avgt   25      413895.143 ?     17800.959  ns/op
IOUtilsContentEqualsPerformanceTest.testContentEqualsIgnoreEOLForFileOld                   avgt   25      405937.862 ?     40555.022  ns/op
IOUtilsContentEqualsPerformanceTest.testContentEqualsIgnoreEOLForStringNew                 avgt   25  1860768966.667 ? 354336311.958  ns/op
IOUtilsContentEqualsPerformanceTest.testContentEqualsIgnoreEOLForStringOld                 avgt   25  5992785770.000 ?1060132999.870  ns/op
IOUtilsContentEqualsPerformanceTest.testSpecialCaseForContentEqualsIgnoreEOLForStringNew   avgt   25        2627.266 ?       844.778  ns/op
IOUtilsContentEqualsPerformanceTest.testSpecialCaseForContentEqualsIgnoreEOLForStringNew2  avgt   25        8504.022 ?      5633.484  ns/op
IOUtilsContentEqualsPerformanceTest.testSpecialCaseForContentEqualsIgnoreEOLForStringOld   avgt   25    85377923.392 ?   7746555.220  ns/op

Found a bug in contentEqualsIgnoreEOLNew2. Will redo contentEqualsIgnoreEOLNew2 tomorrow. Will go sleep now.

XenoAmess avatar Jul 29 '20 18:07 XenoAmess

Hi. I simplified the codes today, and fixed the bugs found yesterday. full test at: https://pastebin.ubuntu.com/p/XNj26hJZYM/ In short:

Benchmark                                                                                  Mode  Cnt           Score           Error  Units
IOUtilsContentEqualsPerformanceTest.testContentEqualsForFileNew                            avgt    5      396240.533 ?     36799.033  ns/op
IOUtilsContentEqualsPerformanceTest.testContentEqualsForFileOld                            avgt    5      433584.396 ?     29788.600  ns/op
IOUtilsContentEqualsPerformanceTest.testContentEqualsForStringNew                          avgt    5   459169873.636 ?  57372500.268  ns/op
IOUtilsContentEqualsPerformanceTest.testContentEqualsForStringOld                          avgt    5  2819825050.000 ? 357333711.445  ns/op
IOUtilsContentEqualsPerformanceTest.testContentEqualsIgnoreEOLForFileNew                   avgt    5      413149.875 ?    248377.525  ns/op
IOUtilsContentEqualsPerformanceTest.testContentEqualsIgnoreEOLForFileNew2                  avgt    5      418270.135 ?     60833.578  ns/op
IOUtilsContentEqualsPerformanceTest.testContentEqualsIgnoreEOLForFileOld                   avgt    5      405679.398 ?     47700.407  ns/op
IOUtilsContentEqualsPerformanceTest.testContentEqualsIgnoreEOLForStringNew                 avgt    5  2592415555.000 ? 113553422.979  ns/op
IOUtilsContentEqualsPerformanceTest.testContentEqualsIgnoreEOLForStringNew2                avgt    5  2038896808.000 ?1221539599.791  ns/op
IOUtilsContentEqualsPerformanceTest.testContentEqualsIgnoreEOLForStringOld                 avgt    5  5809328550.000 ?1231523322.706  ns/op
IOUtilsContentEqualsPerformanceTest.testSpecialCaseForContentEqualsIgnoreEOLForStringNew   avgt    5        2524.221 ?       177.439  ns/op
IOUtilsContentEqualsPerformanceTest.testSpecialCaseForContentEqualsIgnoreEOLForStringNew2  avgt    5        7650.172 ?      1566.588  ns/op
IOUtilsContentEqualsPerformanceTest.testSpecialCaseForContentEqualsIgnoreEOLForStringOld   avgt    5    86502907.284 ?  12466755.564  ns/op

I'm amazed that ContentEqualsIgnoreEOLNew2 runs even faster after the simplify. So I think it is a good time for a re-review.

@sebbASF I implimented the BufferedInput classes we discussed yesterday. Please have a look.

XenoAmess avatar Jul 30 '20 05:07 XenoAmess

And I do think NonThreadSafeButFastBufferedReader and NonThreadSafeButFastBufferedInputStream I added, can be used on several other places in commons-io, to replace original BufferedReader and BufferedInputStream.

For example, FileUtils.performCommand

XenoAmess avatar Jul 30 '20 06:07 XenoAmess

The original comparison methods are easy to follow. It would be good to keep the same clarity by defining new versions of BufferedReader that have good single-threaded performance. Such classes would also be useful elsewhere. So for example BufferedReader bufferedInput1 = toBufferedReader(input1); would become something like: FastBufferedReader bufferedInput1 = toFastBuffer(input1) (*)

where toFastBuffer() works like buffer() but returns an instance of a non-threadsafe FastBufferedReader.

The FastBufferedxxx classes would also be useful in their own right elsewhere in IO. Obviously the documentation would need to make it clear that they are not thread-safe. I suspect they don't need to implement mark (which would make them simpler).

(*) FastBuffer is just a suggestion for the name. Maybe QandDBuffer would be better (Quick and Dirty)!

sebbASF avatar Aug 03 '20 23:08 sebbASF

On Mon, Aug 3, 2020 at 7:42 PM sebbASF [email protected] wrote:

The original comparison methods are easy to follow. It would be good to keep the same clarity by defining new versions of BufferedReader that have good single-threaded performance. Such classes would also be useful elsewhere. So for example BufferedReader bufferedInput1 = toBufferedReader(input1); would become something like: FastBufferedReader bufferedInput1 = toFastBuffer(input1) (*)

where toFastBuffer() works like buffer() but returns an instance of a non-threadsafe FastBufferedReader.

The FastBufferedxxx classes would also be useful in their own right elsewhere in IO. Obviously the documentation would need to make it clear that they are not thread-safe. I suspect they don't need to implement mark (which would make them simpler).

(*) FastBuffer is just a suggestion for the name. Maybe QandDBuffer would be better (Quick and Dirty)!

I would really like to stay away from names like "Fast". Faster than what? What if we come up with something better but incompatible, would that be a "FasterThanFast" or "Fastest" ;-)

We've run into this kind naming issue before and we decide to go with a prefix that describes the actual functionality which is "unsynchronized", see

  • org.apache.commons.io.input.UnsynchronizedByteArrayInputStream
  • org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream

Note that there is precedent for this kind of name in the JRE's copy of Apache's XML code:

  • com.sun.org.apache.xml.internal.security.utils.UnsyncBufferedOutputStream
  • com.sun.org.apache.xml.internal.security.utils.UnsyncByteArrayOutputStream

Gary

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/apache/commons-io/pull/118#issuecomment-668293267, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAJB6N7FXXKQAFHZ5JBELY3R65DPFANCNFSM4NP6TZTQ .

garydgregory avatar Aug 04 '20 01:08 garydgregory

@garydgregory got it. new added class renamed as:

org.apache.commons.io.input.buffer.UnsyncBufferedInputStream org.apache.commons.io.input.buffer.UnsyncBufferedReader org.apache.commons.io.input.buffer.LineEndUnifiedBufferedReader

XenoAmess avatar Aug 04 '20 03:08 XenoAmess

AFAICT the new classes UnsyncBufferedReader etc are not actually used (except in test code).

I would expect all the contentEquals methods to remain exactly the same except for changes to the input sources. The logic should remain unchanged (otherwise the new classes are not proper replacements).

Likewise I would not expect to see any changes to test cases, only new ones for the new classes, and perhaps a few new samples for existing methods where the coverage is incomplete.

sebbASF avatar Aug 05 '20 09:08 sebbASF