bertrandmartel / speed-test-lib

:cloud: JSpeedTest : speed test client library for Java/Android
MIT License
381 stars 119 forks source link

Speed test over time mode #41

Closed gdamich closed 7 years ago

gdamich commented 7 years ago

[This can enhancement]

Was trying to figure how you are doing calculations in your SpeedTestReport class. So, if you put eg Report interval to 200ms, and you are getting eg bytes per second on which time period is calculated that throughput? Per 200ms and than getting average for last one second or? Maybe link to lib code will help me more (was trying to find this in SpeedTestTask.class).

Also, in a case that we are interested in current bytes received/transmit on the nw interface rather than calculated speed, would it be possible to expose that info somehow from Socket or whatever? Like, we set report interval to 100ms and receiving number of bytes transferred every 100ms in your onProgress method?

Sorry if I'm being not so clear...

Best, G

bertrandmartel commented 7 years ago

Was trying to figure how you are doing calculations in your SpeedTestReport class. So, if you put eg Report interval to 200ms, and you are getting eg bytes per second on which time period is calculated that throughput? Per 200ms and than getting average for last one second or? Maybe link to lib code will help me more (was trying to find this in SpeedTestTask.class).

The throughput is calculated from the beginning of the test.

For HTTP download, the start of download is set after the http header are received from the server : here

For FTP download, the start is set after the FTP connect here

For HTTP upload, the start is set after the header have been successfully written here

For FTP upload, the start is set after FTP connect here

The report interval does not indicate any modification of the way the throughput is calculated. Note that you shouldn't perform blocking operation in the listener because it executes on the same thread as the socket reading/writing thread.

HTTP Download

The total packet size is set after the header have been sent : here

After that, all the reading operation are performed in downloadReadingLoop() which read chunk of data with maximum size of 65535 octet

The loop end when there is nothing to read anymore, each iteration calls the onProgress callback if a custom report Interval value wasn't defined by user.

In any case the onProgress get a SpeedTestReport with mSocketInterface.getLiveDownloadReport(); or mSocketInterface.getLiveUploadReport(); which return the current throughput calculation depending on the total packet size and the temporary packet size (total number of bytes received)

If you look at getLiveDownloadReport(), you will see that it calls getReport with the specified mode (download or upload)

The calculation is only performed in this getReport(SpeedTestMode mode) method. The specified part that may interest you is here where the calculation is done using BigDecimal.

render

The process is roughly the same for upload and FTP protocol, let me know if you want an expanded explanation for those

Also, in a case that we are interested in current bytes received/transmit on the nw interface rather than calculated speed, would it be possible to expose that info somehow from Socket or whatever? Like, we set report interval to 100ms and receiving number of bytes transferred every 100ms in your onProgress method?

You have the total number of bytes received with getTemporaryPacketSize() and the total expected number of bytes with getTotalPacketSize(). You could get what you want if you made a diff between the temporary packet size received between 2 onProgress(). I don't see the usecase to have that info per onProgress as the speed test value is calculated from the beginning of the speedtest, maybe you have a specific case ?

gdamich commented 7 years ago

First thanks for very detail replay. It helped me a lot. Indeed my use cases are different. I'm more interested into a performance over a time, rather than having final absolute number. My goal is to have time based graphs for throughput in 200ms sampling as default or any other configurable value. This way I'll be able to see performance over time. In any case, from my current knowledge, you are having most complete android lib for HTTP and FTP testing. So, adding more flexibility like this, lib will be more generic and for more use cases. (This one is perfect for quick speedtest report).

bertrandmartel commented 7 years ago

Do you mean you want to have the throughput value in the report calculated from the last onProgress report and not from the beginning of the test (and thus also the number of bytes received during this interval) ?

gdamich commented 7 years ago

Hi! So throughput is bytes per seconds. And you are calculating it from beginning of the test, having accumulated performance from the beginning. What I would like to have is number of bytes in specific period of time. So, if I'm interested to monitor how much data went in/out buffer every eg. 200ms. And plot that on the time graph. eg. first 200ms was 1MB, next 200ms 2.2MB downloaded/uploaded.

In a case that I use your onProgress with 200ms reporting interval, I'm getting eg in 10th second and 1st 200ms current throughput which was calulated based on other 50 samples (5 samples per second if samppling is 200ms).

Hope it's more clear.

EDIT: Here we are talking how to calculate thrp. You are making calculations simply dividing total transfer bytes with total time needed for that transfer. I'm thinking of more granulated approach as having array of bytes which represent transferred size every 200ms. In that case total throughput can be calcl as average of 5 samples (1 second of transfer) and than average of each calculated result per second.

bertrandmartel commented 7 years ago

This would be the addition of a new "over time" mode with a speed test result on each chunk written/received on the Period defined as reportInterval

bertrandmartel commented 7 years ago

In next release, setting the following parameter will enable this mode :

speedTestSocket.setComputationMethod(ComputationMethod.MEDIAN_INTERVAL);

The new computation mode : https://github.com/bertrandmartel/speed-test-lib/blob/master/jspeedtest/src/main/java/fr/bmartel/speedtest/SpeedTestTask.java#L919-L931