计算每秒字节数(平滑方式) [英] Calculating bytes per second (the smooth way)
问题描述
我正在寻找一种解决方案来计算重复调用的函数
(下文)的每秒传输的字节数。由于它的不准确性,我不要 想简单地将发送的字节除以所用的总时间:它导致在运行几分钟后无法显示快速的速度变化。
I am looking for a solution to calculate the transmitted bytes per second of a repeatedly invoked function
(below). Due to its inaccuracy, I do not want to simply divide the transmitted bytes by the elapsed overall time: it resulted in the inability to display rapid speed changes after running for a few minutes.
预设(大约每50ms调用一次):
The preset (invoked approximately every 50ms):
function uploadProgress(loaded, total){
var bps = ?;
$('#elem').html(bps+' bytes per second');
};
- 如何获取(仅)最后一秒的平均字节数$>
- 有什么其他的计算非闪烁但精确的bps值的做法可用吗? c> / li>
- How to obtain the average bytes per second for (only) the last
n
seconds and is it a good idea? - What other practices for calculating a non-flickering but precise bps value are available?
推荐答案
你的第一个想法不错,它被称为移动平均线,并提供您定期调用更新功能,您只需要保留一个队列(一个 FIFO缓冲区):
Your first idea is not bad, it's called a moving average, and providing you call your update function in regular intervals you only need to keep a queue (a FIFO buffer) of a constant length:
var WINDOW_SIZE = 10; var queue = []; function updateQueue(newValue) { // fifo with a fixed length queue.push(newValue); if (queue.length > WINDOW_SIZE) queue.shift(); } function getAverageValue() { // if the queue has less than 10 items, decide if you want to calculate // the average anyway, or return an invalid value to indicate "insufficient data" if (queue.length < WINDOW_SIZE) { // you probably don't want to throw if the queue is empty, // but at least consider returning an 'invalid' value in order to // display something like "calculating..." return null; } // calculate the average value var sum = 0; for (var i = 0; i < queue.length; i++) { sum += queue[i]; } return sum / queue.length; } // calculate the speed and call `updateQueue` every second or so var updateTimer = setInterval(..., 1000);
避免计算速度突然变化的更简单的方法是使用,rel =nofollow noreferrer> http://en.wikipedia.org/wiki/Low-pass_filter#Discrete-time_realization PT1滤波器的简单离散近似将是:
An even simpler way to avoid sudden changes in calculated speed would be to use a low-pass filter. A simple discrete approximation of the PT1 filter would be:
其中
u [k]
是输入(或实际值)在样本k
,y [k]
是输出(或过滤值 )在样本k
和T
是时间常数(较大T
意味着y
将跟随u
更慢)。Where
u[k]
is the input (or actual value) at samplek
,y[k]
is the output (or filtered value) at samplek
, andT
is the time constant (largerT
means thaty
will followu
more slowly).这将被翻译成如下:
var speed = null; var TIME_CONSTANT = 5; function updateSpeed(newValue) { if (speed === null) { speed = newValue; } else { speed += (newValue - speed) / TIME_CONSTANT; } } function getFilteredValue() { return speed; }
这两种解决方案都会给出类似的结果(至少您的目的),而后一个似乎有点简单(并且需要更少的内存)。
Both solutions will give similar results (for your purpose at least), and the latter one seems a bit simpler (and needs less memory).
此外,我不会更新快速的值。过滤只能以50ms的刷新率将闪烁变为摆动。我不认为任何人都希望上传速度以每秒多次刷新率(甚至几秒钟)显示。
Also, I wouldn't update the value that fast. Filtering will only turn "flickering" into "swinging" at a refresh rate of 50ms. I don't think anybody expects to have an upload speed shown at a refresh rate of more than once per second (or even a couple of seconds).
这篇关于计算每秒字节数(平滑方式)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
- How to obtain the average bytes per second for (only) the last