Some performance optimizations and improved accuracy
This commit is contained in:
@@ -7,9 +7,8 @@ import { copy_text } from "../util/Util.svelte";
|
|||||||
|
|
||||||
let running = false
|
let running = false
|
||||||
let data_received = 0
|
let data_received = 0
|
||||||
let update_interval = 100
|
const update_interval = 100
|
||||||
let test_duration = 0
|
let test_duration = 0
|
||||||
let current_duration = 0
|
|
||||||
let latency = 0
|
let latency = 0
|
||||||
const start = async (dur = 6000) => {
|
const start = async (dur = 6000) => {
|
||||||
if (running) {
|
if (running) {
|
||||||
@@ -20,11 +19,11 @@ const start = async (dur = 6000) => {
|
|||||||
test_duration = dur
|
test_duration = dur
|
||||||
data_received = 0
|
data_received = 0
|
||||||
|
|
||||||
let latency_start = Date.now()
|
const latency_start = Date.now()
|
||||||
|
|
||||||
// Start a request for 10 GB of random data. We omit credentials so the
|
// Start a request for 10 GB of random data. We omit credentials so the
|
||||||
// server does fetch the API key from the database which increases latency
|
// server does fetch the API key from the database which increases latency
|
||||||
let req = await fetch(
|
const req = await fetch(
|
||||||
window.api_endpoint+"/misc/speedtest?limit="+10e9,
|
window.api_endpoint+"/misc/speedtest?limit="+10e9,
|
||||||
{credentials: "omit"},
|
{credentials: "omit"},
|
||||||
)
|
)
|
||||||
@@ -32,17 +31,16 @@ const start = async (dur = 6000) => {
|
|||||||
// Measure request latency
|
// Measure request latency
|
||||||
latency = Date.now() - latency_start
|
latency = Date.now() - latency_start
|
||||||
|
|
||||||
let reader = req.body.getReader();
|
const reader = req.body.getReader();
|
||||||
|
|
||||||
measure_speed(reader, update_interval, test_duration)
|
measure_speed(reader, update_interval, test_duration)
|
||||||
|
|
||||||
// Read from the connection, add the received data to the total
|
|
||||||
while(true) {
|
while(true) {
|
||||||
const {done, value} = await reader.read();
|
const {done, value} = await reader.read()
|
||||||
if (done) {
|
if (done) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
data_received += value.length;
|
data_received += value.byteLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
running = false
|
running = false
|
||||||
@@ -51,39 +49,34 @@ const start = async (dur = 6000) => {
|
|||||||
// Average speed for the whole test
|
// Average speed for the whole test
|
||||||
let speed = 0
|
let speed = 0
|
||||||
let result_link = ""
|
let result_link = ""
|
||||||
|
let current_duration = 0
|
||||||
|
|
||||||
const measure_speed = (reader, update_interval, test_duration) => {
|
const measure_speed = (reader, update_interval, test_duration) => {
|
||||||
// We measure the transfer speed for 1/3 the duration of the test, after
|
speed = 0
|
||||||
// that we start overwriting the lowest speed values with the highest speed
|
result_link = ""
|
||||||
// values to account for slow start and jitter. At the end of the test the
|
|
||||||
// average speed in this array is the final result.
|
// This slice contains the speed measurements for 1/3 the duration of the
|
||||||
let hist = new Array((test_duration/3)/update_interval)
|
// test. This value is averaged and if the average is higher than the
|
||||||
|
// previously calculated average then it is saved
|
||||||
|
const hist = new Uint32Array((test_duration/3)/update_interval)
|
||||||
let idx = 0
|
let idx = 0
|
||||||
let previous_transferred = 0
|
let previous_transferred = 0
|
||||||
let start = Date.now()
|
const start = Date.now()
|
||||||
|
|
||||||
console.debug("History length", hist.length)
|
console.debug("Test duration", test_duration, "interval", update_interval, "history", hist.length)
|
||||||
|
|
||||||
let measure = async () => {
|
let measure = async () => {
|
||||||
let current_speed = data_received - previous_transferred
|
// Update the speed measurement
|
||||||
|
hist[idx%hist.length] = data_received - previous_transferred
|
||||||
previous_transferred = data_received
|
previous_transferred = data_received
|
||||||
|
|
||||||
// If the current measurement is higher than the last measurement we
|
|
||||||
// save it in the speed history array
|
|
||||||
if (hist[idx%hist.length] === undefined || current_speed > hist[idx%hist.length]) {
|
|
||||||
hist[idx%hist.length] = current_speed
|
|
||||||
}
|
|
||||||
idx++
|
idx++
|
||||||
|
|
||||||
// Calculate the average of the speed measurements
|
// Calculate the average of all the speed measurements
|
||||||
let sum = hist.reduce((acc, val) => {
|
const sum = hist.reduce((acc, val) => acc + val, 0)
|
||||||
if (val !== undefined) {
|
const new_speed = (sum/hist.length)*(1000/update_interval)
|
||||||
acc.sum += val
|
if (new_speed > speed) {
|
||||||
acc.count++
|
speed = new_speed
|
||||||
}
|
}
|
||||||
return acc
|
|
||||||
}, {sum: 0, count: 0})
|
|
||||||
speed = (sum.sum/sum.count)*(1000/update_interval)
|
|
||||||
|
|
||||||
// Only used for the progress bar
|
// Only used for the progress bar
|
||||||
current_duration = Date.now() - start
|
current_duration = Date.now() - start
|
||||||
@@ -94,10 +87,13 @@ const measure_speed = (reader, update_interval, test_duration) => {
|
|||||||
// single test which significantly impacts results
|
// single test which significantly impacts results
|
||||||
setTimeout(measure, update_interval - (current_duration-(idx*update_interval)))
|
setTimeout(measure, update_interval - (current_duration-(idx*update_interval)))
|
||||||
} else {
|
} else {
|
||||||
console.debug("Done! Test ran for", current_duration, )
|
// Test is done, break the reader out of the counting loop
|
||||||
current_duration = 0
|
|
||||||
await reader.cancel()
|
await reader.cancel()
|
||||||
|
|
||||||
|
console.debug("Done! Test ran for", current_duration)
|
||||||
|
current_duration = 0
|
||||||
|
|
||||||
|
// Update the URL so the results can be shared
|
||||||
history.replaceState(
|
history.replaceState(
|
||||||
undefined,
|
undefined,
|
||||||
undefined,
|
undefined,
|
||||||
@@ -107,15 +103,17 @@ const measure_speed = (reader, update_interval, test_duration) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Start the measurement loop
|
||||||
setTimeout(measure, update_interval)
|
setTimeout(measure, update_interval)
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
|
// Parse the results saved in the URL, if any
|
||||||
if (window.location.hash[0] === "#") {
|
if (window.location.hash[0] === "#") {
|
||||||
var hash = window.location.hash.replace("#", "");
|
const hash = window.location.hash.replace("#", "");
|
||||||
let result = hash.replace("#", "").split('&').reduce((res, item) => {
|
const result = hash.replace("#", "").split('&').reduce((res, item) => {
|
||||||
let parts = item.split('=')
|
const parts = item.split('=')
|
||||||
let n = Number(parts[1])
|
const n = Number(parts[1])
|
||||||
if (n !== NaN) {
|
if (n !== NaN) {
|
||||||
res[parts[0]] = n
|
res[parts[0]] = n
|
||||||
}
|
}
|
||||||
@@ -153,8 +151,9 @@ onMount(() => {
|
|||||||
<div class="highlight_shaded">Latency {latency}ms</div>
|
<div class="highlight_shaded">Latency {latency}ms</div>
|
||||||
<div class="highlight_shaded">Received {formatDataVolume(data_received, 3)}</div>
|
<div class="highlight_shaded">Received {formatDataVolume(data_received, 3)}</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- Progress bar starts at log10(3) becasue the we want the lowest speed shown to be 1 kB/s -->
|
<!-- Progress bar starts at log10(6) because the we want the lowest speed
|
||||||
<ProgressBar animation="linear" speed={update_interval} used={Math.log10(speed*8)-5} total={5}/>
|
shown to be 1 Mbps (1e6 bits) -->
|
||||||
|
<ProgressBar animation="linear" speed={update_interval} used={Math.log10(speed*8)-6} total={4}/>
|
||||||
|
|
||||||
<div class="speed_grid">
|
<div class="speed_grid">
|
||||||
<div>↑</div>
|
<div>↑</div>
|
||||||
@@ -162,10 +161,8 @@ onMount(() => {
|
|||||||
<div>↑</div>
|
<div>↑</div>
|
||||||
<div>↑</div>
|
<div>↑</div>
|
||||||
<div>↑</div>
|
<div>↑</div>
|
||||||
<div>↑</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="speed_grid">
|
<div class="speed_grid">
|
||||||
<div>100 kb</div>
|
|
||||||
<div>1 Mb</div>
|
<div>1 Mb</div>
|
||||||
<div>10 Mb</div>
|
<div>10 Mb</div>
|
||||||
<div>100 Mb</div>
|
<div>100 Mb</div>
|
||||||
|
Reference in New Issue
Block a user