]> Piment Noir Git Repositories - e-mobility-charging-stations-simulator.git/commitdiff
perf: speed up mean and median computation
authorJérôme Benoit <jerome.benoit@sap.com>
Wed, 2 Jul 2025 17:44:11 +0000 (19:44 +0200)
committerJérôme Benoit <jerome.benoit@sap.com>
Wed, 2 Jul 2025 17:44:11 +0000 (19:44 +0200)
Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com>
13 files changed:
scripts/bundle.js
src/charging-station/ChargingStation.ts
src/charging-station/ocpp/1.6/OCPP16ServiceUtils.ts
src/charging-station/ocpp/2.0/OCPP20ServiceUtils.ts
src/charging-station/ocpp/OCPPIncomingRequestService.ts
src/charging-station/ocpp/OCPPRequestService.ts
src/charging-station/ocpp/OCPPResponseService.ts
src/charging-station/ui-server/UIServerUtils.ts
src/utils/Configuration.ts
src/utils/StatisticUtils.ts
src/utils/Utils.ts
tests/charging-station/Helpers.test.ts
tests/utils/ErrorUtils.test.ts

index a41b28ffc2516f0c5977b059311e399fbeb7082e..21080354efb9ec48f5feef99915277f29728e891 100644 (file)
@@ -1,4 +1,5 @@
 /* eslint-disable n/no-unpublished-import */
+
 import chalk from 'chalk'
 import { build } from 'esbuild'
 import { clean } from 'esbuild-plugin-clean'
index fae2f7edff15597db8e0d729c23b196aac46da33..de21923415e097637a9c912f41562aaf3d38be42 100644 (file)
@@ -228,7 +228,7 @@ export class ChargingStation extends EventEmitter {
     this.evses = new Map<number, EvseStatus>()
     this.requests = new Map<string, CachedRequest>()
     this.flushingMessageBuffer = false
-    this.messageQueue = new Array<string>()
+    this.messageQueue = [] as string[]
     this.sharedLRUCache = SharedLRUCache.getInstance()
     this.idTagsCache = IdTagsCache.getInstance()
     this.chargingStationWorkerBroadcastChannel = new ChargingStationWorkerBroadcastChannel(this)
@@ -1812,10 +1812,8 @@ export class ChargingStation extends EventEmitter {
         this,
         this.stationInfo.amperageLimitationOcppKey,
         // prettier-ignore
-        (
-          // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-          this.stationInfo.maximumAmperage! * getAmperageLimitationUnitDivider(this.stationInfo)
-        ).toString()
+        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+        (this.stationInfo.maximumAmperage! * getAmperageLimitationUnitDivider(this.stationInfo)).toString()
       )
     }
     if (getConfigurationKey(this, StandardParametersKey.SupportedFeatureProfiles) == null) {
index 010bd5b20ecd7be8b13ded1f2e079f1cc317c691..dba9fbf964923b23779bd141d10ebf1be9adcc4e 100644 (file)
@@ -415,7 +415,7 @@ export class OCPP16ServiceUtils extends OCPPServiceUtils {
     moduleName?: string,
     methodName?: string
   ): JSONSchemaType<T> {
-    return super.parseJsonSchemaFile<T>(
+    return OCPPServiceUtils.parseJsonSchemaFile<T>(
       relativePath,
       OCPPVersion.VERSION_16,
       moduleName,
index a02a3cea709781f96c1a60068227a72882993dac..82bd9f133a0a54426ccea7465edbd0bbe2fd5479 100644 (file)
@@ -11,7 +11,7 @@ export class OCPP20ServiceUtils extends OCPPServiceUtils {
     moduleName?: string,
     methodName?: string
   ): JSONSchemaType<T> {
-    return super.parseJsonSchemaFile<T>(
+    return OCPPServiceUtils.parseJsonSchemaFile<T>(
       relativePath,
       OCPPVersion.VERSION_201,
       moduleName,
index ca2ea97affb4e84d3c411ced461fb74744966bbb..15981f7e42c22513d5f074a9ee840636da50a3f4 100644 (file)
@@ -14,6 +14,7 @@ import { OCPPError } from '../../exception/index.js'
 import { logger } from '../../utils/index.js'
 import { OCPPConstants } from './OCPPConstants.js'
 import { ajvErrorsToErrorType } from './OCPPServiceUtils.js'
+
 type Ajv = _Ajv.default
 // eslint-disable-next-line @typescript-eslint/no-redeclare
 const Ajv = _Ajv.default
index d847a6e8de120c78bd4c47e3a275df33af3e5550..439d656fbd1da7480a0998905c8f1b181592795c 100644 (file)
@@ -34,6 +34,7 @@ import {
   convertDateToISOString,
   getMessageTypeString,
 } from './OCPPServiceUtils.js'
+
 type Ajv = _Ajv.default
 // eslint-disable-next-line @typescript-eslint/no-redeclare
 const Ajv = _Ajv.default
index a4dfa834b8d196ac1b558dec66ac48660caf97cb..420358497d8670550a93c59ee78d648719da2d9e 100644 (file)
@@ -12,6 +12,7 @@ import type {
 import { OCPPError } from '../../exception/index.js'
 import { Constants, logger } from '../../utils/index.js'
 import { ajvErrorsToErrorType } from './OCPPServiceUtils.js'
+
 type Ajv = _Ajv.default
 // eslint-disable-next-line @typescript-eslint/no-redeclare
 const Ajv = _Ajv.default
index 2e3ea7da7b437cac202be045a232ed112e1ef6c7..fd7774406b36a47864e576f3f4c5873c72e39494 100644 (file)
@@ -60,6 +60,5 @@ export const getProtocolAndVersion = (protocolStr: string): [Protocol, ProtocolV
 }
 
 export const isLoopback = (address: string): boolean => {
-  // eslint-disable-next-line no-useless-escape
-  return /^localhost$|^127(?:\.\d+){0,2}\.\d+$|^(?:0*\:)*?:?0*1$/i.test(address)
+  return /^localhost$|^127(?:\.\d+){0,2}\.\d+$|^(?:0*:)*?:?0*1$/i.test(address)
 }
index 9a3eec8ad2eeef9b1ff39862fd38d522aba048cd..a6482afe27ce4c1ecb4cbd7dd15aa489033bd1a0 100644 (file)
@@ -591,7 +591,7 @@ export class Configuration {
           consoleWarnOnce(
             `${chalk.green(logPrefix())} ${chalk.yellow(
               // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
-              `${FileType.Configuration} ${this.configurationFile} file have changed, reload`
+              `${FileType.Configuration} ${Configuration.configurationFile} file have changed, reload`
             )}`
           )
           delete Configuration.configurationData
index 4b87465daec17fb4446924f19637f69e31009b09..fc453236f4c82462624d4b604d723aeb52924440 100644 (file)
@@ -2,19 +2,23 @@ export const mean = (dataSet: number[]): number => {
   if (Array.isArray(dataSet) && dataSet.length === 0) {
     return 0
   }
-  return dataSet.reduce((accumulator, num) => accumulator + num, 0) / dataSet.length
+  if (Array.isArray(dataSet) && dataSet.length === 1) {
+    return dataSet[0]
+  }
+  return dataSet.reduce((accumulator, number) => accumulator + number, 0) / dataSet.length
 }
 
 export const median = (dataSet: number[]): number => {
   if (Array.isArray(dataSet) && dataSet.length === 0) {
     return 0
   }
-  const sortedDataSet = dataSet.slice().sort((a, b) => a - b)
-  const length = sortedDataSet.length
-  if (length % 2 === 0) {
-    return (sortedDataSet[length / 2 - 1] + sortedDataSet[length / 2]) / 2
+  if (Array.isArray(dataSet) && dataSet.length === 1) {
+    return dataSet[0]
   }
-  return sortedDataSet[Math.floor(length / 2)]
+  const sortedDataSet = dataSet.slice().sort((a, b) => a - b)
+  return (
+    (sortedDataSet[(sortedDataSet.length - 1) >> 1] + sortedDataSet[sortedDataSet.length >> 1]) / 2
+  )
 }
 
 export const min = (...args: number[]): number =>
@@ -63,7 +67,7 @@ export const stdDeviation = (dataSet: number[], dataSetAverage: number = mean(da
     return 0
   }
   return Math.sqrt(
-    dataSet.reduce((accumulator, num) => accumulator + Math.pow(num - dataSetAverage, 2), 0) /
+    dataSet.reduce((accumulator, num) => accumulator + (num - dataSetAverage) ** 2, 0) /
       (dataSet.length - 1)
   )
 }
index efa0ec5f20da5abdae74d9148ae4a3cac6b6f1dc..c8a8b14d3fe54e358b695c3159f933bcab9ecb9f 100644 (file)
@@ -47,7 +47,7 @@ export const has = (property: PropertyKey, object: null | object | undefined): b
   if (object == null) {
     return false
   }
-  return Object.prototype.hasOwnProperty.call(object, property)
+  return Object.hasOwn(object, property)
 }
 
 const type = (value: unknown): string => {
@@ -255,7 +255,7 @@ export const getRandomFloat = (max = Number.MAX_VALUE, min = 0): number => {
  * @returns The rounded number.
  */
 export const roundTo = (numberValue: number, scale: number): number => {
-  const roundPower = Math.pow(10, scale)
+  const roundPower = 10 ** scale
   return Math.round(numberValue * roundPower * (1 + Number.EPSILON)) / roundPower
 }
 
@@ -334,7 +334,7 @@ export const insertAt = (str: string, subStr: string, pos: number): string =>
  * @returns delay in milliseconds
  */
 export const exponentialDelay = (retryNumber = 0, delayFactor = 100): number => {
-  const delay = Math.pow(2, retryNumber) * delayFactor
+  const delay = 2 ** retryNumber * delayFactor
   const randomSum = delay * 0.2 * secureRandom() // 0-20% of the delay
   return delay + randomSum
 }
index cdba018197e87422783d0c8ed9b51df956c859bb..93fa649508b2243c01a1fa636187f95071c6e977 100644 (file)
@@ -1,4 +1,5 @@
 /* eslint-disable @typescript-eslint/no-unsafe-member-access */
+
 import { expect } from '@std/expect'
 import { describe, it } from 'node:test'
 
@@ -202,7 +203,9 @@ await describe('Helpers test suite', async () => {
     t.mock.method(logger, 'warn')
     checkStationInfoConnectorStatus(1, {} as ConnectorStatus, 'log prefix |', 'test-template.json')
     expect(logger.warn.mock.calls.length).toBe(0)
-    const connectorStatus = { status: ConnectorStatusEnum.Available } as ConnectorStatus
+    const connectorStatus = {
+      status: ConnectorStatusEnum.Available,
+    } as ConnectorStatus
     checkStationInfoConnectorStatus(1, connectorStatus, 'log prefix |', 'test-template.json')
     expect(logger.warn.mock.calls.length).toBe(1)
     expect(connectorStatus.status).toBeUndefined()
index de7a2a36f1c1480bcf2f36e4e85c12001a6250cc..9da6f63dadaa2c6f4e25317b58a05980f3c47343 100644 (file)
@@ -1,4 +1,5 @@
 /* eslint-disable @typescript-eslint/no-unsafe-member-access */
+
 import { expect } from '@std/expect'
 import { describe, it } from 'node:test'