Skip to content
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

Improve speed calculation #28

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

logiclrd
Copy link

When using this library on a Linux system, I am finding wildly inaccurate BytesPerSecond values being supplied in the CopyProgress instances passed into the progress callback functor. Specifically, they seem to be on the order of 100 times larger than the actual transfer speed. I'm not exactly sure what the cause is, but I suspect that Stopwatch is under-reporting short durations, so that the loop thinks each buffer fill it sends takes less time than it does and is thus much faster than it really is.

This PR updates the code to use an average over a window of recent samples instead of trying to capture the time of each individual write operation. It adds a class SpeedCalculator which manages a buffer of samples. The loops then supply a new sample each time a write operation completes. SpeedCalculator automatically takes care of timestamping these supplied samples. Later, a method CalculateBytesPerSecond uses the difference between the first and last sample in the buffer. As long as DateTime.UtcNow is not subject to any significant jitter, this should much more accurately capture the overall transfer speed. The buffer is kept trimmed to a specified duration (a constant currently set to 10 seconds).

There is also handling for if the caller somehow ends up going backward in the stream and supplying samples with earlier position values. The invariant that the samples have monotonically-increasing position values is maintained.

The two loops that calculate transfer speeds and pass CopyProgress instances to a progress callback are updated to use CopyProgress to compute the speed.

The SpeedCalculator class is thoroughly commented and defensively programmed.

Updated ProgressStreamContent.cs and StreamExtensions.cs to use SpeedCalculator to compute the bytesPerSecond value to be passed into the CopyProgress constructor. Deleted the singleTime Stopwatch from each loop.
@logiclrd
Copy link
Author

SpeedCalculator is not threadsafe. It doesn't need to be with the current usage.

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.

None yet

1 participant