calc-stats
Advanced tools
Comparing version 2.2.0 to 2.3.0
@@ -29,2 +29,3 @@ // export enum STATS_ENUM { | ||
| "modes" | ||
| "product" | ||
| "range" | ||
@@ -112,2 +113,3 @@ | "sum" | ||
async?: boolean; | ||
chunked?: boolean; | ||
noData?: number | string; | ||
@@ -120,1 +122,14 @@ filter?: ({ valid, index, value }: { valid: number; index: number; value: number | string }) => boolean; | ||
): any; | ||
export function calcStats( | ||
data: number[] | string[] | any, | ||
options?: { | ||
async?: boolean; | ||
chunked?: boolean; | ||
noData?: number | string; | ||
filter?: ({ valid, index, value }: { valid: number; index: number; value: number | string }) => boolean; | ||
precise?: boolean; | ||
precise_max_decimal_digits?: number; | ||
stats?: STAT[] | Readonly<STAT[]>; | ||
} | ||
): any; |
@@ -5,2 +5,5 @@ const { getOrCreateIterator } = require("iter-fun"); | ||
// n === n is a lot quicker than !isNaN(n) | ||
const isValidNumber = n => typeof n === "number" && n === n; | ||
const computeVariance = ({ count, histogram, mean_value, precise = false }) => { | ||
@@ -48,5 +51,8 @@ if (precise) { | ||
precise_max_decimal_digits = 100, | ||
stats | ||
stats, | ||
timed = false | ||
} = { debugLevel: 0 } | ||
) { | ||
const start = timed ? performance.now() : 0; | ||
if (stats) { | ||
@@ -124,2 +130,29 @@ // validate stats argument | ||
let process; | ||
// hoisting functions outside of conditionals | ||
// in order to help compilers optimize | ||
const initial_process = value => { | ||
if (needValid) valid = 1; | ||
if (needMin) min = value; | ||
if (needMax) max = value; | ||
if (needProduct) product = value; | ||
if (needSum) sum = value; | ||
if (needHistogram) { | ||
histogram[value] = { n: value, ct: 1 }; | ||
} | ||
process = subsequent_process; | ||
}; | ||
const subsequent_process = value => { | ||
if (needValid) valid++; | ||
if (needMin && value < min) min = value; | ||
if (needMax && value > max) max = value; | ||
if (needProduct) product *= value; | ||
if (needSum) sum += value; | ||
if (needHistogram) { | ||
if (value in histogram) histogram[value].ct++; | ||
else histogram[value] = { n: value, ct: 1 }; | ||
} | ||
}; | ||
if (precise) { | ||
@@ -129,4 +162,4 @@ process = value => { | ||
if (needValid) valid++; | ||
if (needMin && (min === undefined || compare(value, min) === "<")) min = value; | ||
if (needMax && (max === undefined || compare(value, max) === ">")) max = value; | ||
if (needMin && (typeof min === "undefined" || compare(value, min) === "<")) min = value; | ||
if (needMax && (typeof max === "undefined" || compare(value, max) === ">")) max = value; | ||
if (needProduct) product = valid === 1 ? value : multiply(product, value); | ||
@@ -140,13 +173,3 @@ if (needSum) sum = add(sum, value); | ||
} else { | ||
process = value => { | ||
if (needValid) valid++; | ||
if (needMin && (min === undefined || value < min)) min = value; | ||
if (needMax && (max === undefined || value > max)) max = value; | ||
if (needProduct) product = valid === 1 ? value : product * value; | ||
if (needSum) sum += value; | ||
if (needHistogram) { | ||
if (value in histogram) histogram[value].ct++; | ||
else histogram[value] = { n: value, ct: 1 }; | ||
} | ||
}; | ||
process = initial_process; | ||
} | ||
@@ -158,3 +181,3 @@ | ||
index++; | ||
if (typeof value === "number" && !isNaN(value) && value !== noData && filter({ valid, index, value }) === true) { | ||
if (isValidNumber(value) && value !== noData && filter({ valid, index, value }) === true) { | ||
process(value); | ||
@@ -167,3 +190,3 @@ } else if (needInvalid) { | ||
step = value => { | ||
if (typeof value === "number" && !isNaN(value) && value !== noData) { | ||
if (isValidNumber(value) && value !== noData) { | ||
process(value); | ||
@@ -177,3 +200,3 @@ } else if (needInvalid) { | ||
index++; | ||
if (typeof value === "number" && !isNaN(value) && filter({ valid, index, value }) === true) { | ||
if (isValidNumber(value) && filter({ valid, index, value }) === true) { | ||
process(value); | ||
@@ -186,3 +209,3 @@ } else if (needInvalid) { | ||
step = value => { | ||
if (typeof value === "number" && !isNaN(value)) { | ||
if (isValidNumber(value)) { | ||
process(value); | ||
@@ -256,3 +279,10 @@ } else if (needInvalid) { | ||
} | ||
if (timed) { | ||
const duration = Math.round(performance.now() - start); | ||
if (duration > 2000) { | ||
console.log("[calc-stats] took " + Math.round(duration / 1000).toLocaleString() + " seconds"); | ||
} else { | ||
console.log("[calc-stats] took " + duration.toLocaleString() + " milliseconds"); | ||
} | ||
} | ||
return results; | ||
@@ -272,6 +302,16 @@ }; | ||
} else { | ||
for (let value of iter) { | ||
for (let v of value) { | ||
step(v); | ||
// array of arrays or array of typed arrays | ||
if (Array.isArray(data) && data[0].length) { | ||
for (let i = 0; i < data.length; i++) { | ||
const value = data[i]; | ||
for (let ii = 0; ii < value.length; ii++) { | ||
step(value[ii]); | ||
} | ||
} | ||
} else { | ||
for (let value of iter) { | ||
for (let v of value) { | ||
step(v); | ||
} | ||
} | ||
} | ||
@@ -278,0 +318,0 @@ return finish(); |
{ | ||
"name": "calc-stats", | ||
"version": "2.2.0", | ||
"version": "2.3.0", | ||
"description": "Memory-Aware Statistical Calculations", | ||
"main": "calc-stats.js", | ||
"main": "./calc-stats.js", | ||
"types": "calc-stats.d.ts", | ||
@@ -14,3 +14,3 @@ "files": [ | ||
"format": "npx prettier --arrow-parens=avoid --print-width=120 --trailing-comma=none --write *.js *.ts", | ||
"test": "node test.js", | ||
"test": "TEST_TIMED=true node test.js", | ||
"test:ts": "npx ts-node test.ts" | ||
@@ -48,4 +48,5 @@ }, | ||
"devDependencies": { | ||
"flat-iter": "^0.3.0", | ||
"flug": "^2.6.0" | ||
} | ||
} |
@@ -121,1 +121,9 @@ # calc-stats | ||
``` | ||
## timed | ||
If you want to log how long it takes to calculate statistics, | ||
set `{ timed: true }`; | ||
```js | ||
calcStats(data, { timed: true }); | ||
// [calc-stats] took 3 seconds | ||
``` |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
25237
446
128
2