-
Notifications
You must be signed in to change notification settings - Fork 300
Description
Profiling of Asterisk-Java reveals a large amount of CPU spent in java.util.Scanner.
The reality is that the vast majority of this CPU time is actually in the underlying Socket.
However there are still significant gains to be made by replacing the usage of java.util.Scanner.
I've put together 2 classes which replace java.util.Scanner, one for each of the 2 line endings that Asterisk-Java uses \n and \r\n. The \r\n implementation extends the \n implementation and is quite minimal, but helps to keep things as simple as possible.
I've added a factory (org.asteriskjava.util.internal.streamreader.FastScannerFactory) for creating the Scanner, which returns the correct implementation given the Pattern. The factory also provides a static method to force use of java.util.Scanner : useLegacyScanner(boolean b).
The new implementations are approximately 8 times faster than java.util.Scanner.
I've also provided a number of JUnit tests:
FastScannerDeterministicTest
FastScannerSpeedTest
FastScannerRandomTest
FastScannerSpeedTestOnSocket
FastScannerRandomTest is probably the most significant test. It builds random test data and runs the test data through both java.util.Scanner and the new implementations and compares the output. I have run more than 50GB of test data through this Test which was instrumental in finding small discrepancies in behavior.
Finally our application uses AMI and AGI heavily and I have tested the new Scanners in this code base under heavy load, and there are no apparent problems.
Whilst working on this I've addressed the issues around pull request #231 by @elara-leitstellentechnik
The commit is 7d5bc10