perf: switch benchmarks to factorial(50000)
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Thu, 28 Mar 2024 18:30:54 +0000 (19:30 +0100)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Thu, 28 Mar 2024 18:30:54 +0000 (19:30 +0100)
Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
27 files changed:
benchmarks/benchmarks-utils.cjs
benchmarks/internal/bench.mjs
examples/typescript/http-server-pool/express-cluster/package.json
examples/typescript/http-server-pool/express-cluster/src/worker.ts
examples/typescript/http-server-pool/express-hybrid/package.json
examples/typescript/http-server-pool/express-hybrid/src/request-handler-worker.ts
examples/typescript/http-server-pool/express-worker_threads/package.json
examples/typescript/http-server-pool/express-worker_threads/src/worker.ts
examples/typescript/http-server-pool/fastify-cluster/package.json
examples/typescript/http-server-pool/fastify-cluster/src/worker.ts
examples/typescript/http-server-pool/fastify-hybrid/package.json
examples/typescript/http-server-pool/fastify-hybrid/src/request-handler-worker.ts
examples/typescript/http-server-pool/fastify-worker_threads/package.json
examples/typescript/http-server-pool/fastify-worker_threads/src/worker.ts
examples/typescript/websocket-server-pool/ws-cluster/requests.js
examples/typescript/websocket-server-pool/ws-cluster/src/worker.ts
examples/typescript/websocket-server-pool/ws-hybrid/requests.js
examples/typescript/websocket-server-pool/ws-hybrid/src/request-handler-worker.ts
examples/typescript/websocket-server-pool/ws-hybrid/src/websocket-server-worker.ts
examples/typescript/websocket-server-pool/ws-worker_threads/requests.js
examples/typescript/websocket-server-pool/ws-worker_threads/src/main.ts
examples/typescript/websocket-server-pool/ws-worker_threads/src/worker.ts
tests/pools/cluster/dynamic.test.mjs
tests/pools/cluster/fixed.test.mjs
tests/pools/thread/dynamic.test.mjs
tests/pools/thread/fixed.test.mjs
tests/test-utils.cjs

index b4a0d9bd8dd518420330ea5700fe1972b6995027..c2de0d5e65fbda3fc2413dff4142ca4d56774443 100644 (file)
@@ -197,25 +197,36 @@ const jsonIntegerSerialization = n => {
 }
 
 /**
- * Intentionally inefficient implementation.
  * @param {number} n - The number of fibonacci numbers to generate.
  * @returns {number} - The nth fibonacci number.
  */
 const fibonacci = n => {
-  if (n <= 1) return n
-  return fibonacci(n - 1) + fibonacci(n - 2)
+  n = BigInt(n)
+  let current = 1n
+  let previous = 0n
+  while (--n) {
+    const tmp = current
+    current += previous
+    previous = tmp
+  }
+  return current
 }
 
 /**
- * Intentionally inefficient implementation.
  * @param {number} n - The number to calculate the factorial of.
  * @returns {number} - The factorial of n.
  */
 const factorial = n => {
-  if (n === 0) {
-    return 1
+  if (n === 0 || n === 1) {
+    return 1n
+  } else {
+    n = BigInt(n)
+    let factorial = 1n
+    for (let i = 1n; i <= n; i++) {
+      factorial *= i
+    }
+    return factorial
   }
-  return factorial(n - 1) * n
 }
 
 const readWriteFiles = (
index b59514d225b45adf149f011798156af1a7bcf675..62eefe64daa62bc91e042d3718c9a31701c6fdf9 100644 (file)
@@ -11,8 +11,8 @@ import { runPoolifierPoolBenchmark } from '../benchmarks-utils.cjs'
 const poolSize = availableParallelism()
 const taskExecutions = 1
 const workerData = {
-  function: TaskFunctions.jsonIntegerSerialization,
-  taskSize: 1000
+  function: TaskFunctions.factorial,
+  taskSize: 50000
 }
 
 // FixedThreadPool
index fe37e82654912b80701facef240d3b5c10d0b57a..ddbb5d6c82c0e630863cab45c301358be9e97a3f 100644 (file)
@@ -15,7 +15,7 @@
     "start:esm": "node --enable-source-maps dist/main.js",
     "test": "echo \"Error: no test specified\" && exit 1",
     "benchmark:echo": "autocannon -c 100 -d 30 -p 10 -m POST -H Content-Type=application/json -b '{\"key1\":\"value1\", \"key2\":\"value2\"}' http://localhost:8080/api/echo",
-    "benchmark:factorial": "autocannon -c 100 -d 30 -p 10 http://localhost:8080/api/factorial/30"
+    "benchmark:factorial": "autocannon -c 100 -d 30 -p 10 http://localhost:8080/api/factorial/50000"
   },
   "keywords": [],
   "author": "",
index e04900ab2474afa7833c6bde6c5086030ab3882f..da2e9ad7fc68abece6a9339730b5c0d049dee574 100644 (file)
@@ -9,11 +9,17 @@ import type { WorkerData, WorkerResponse } from './types.js'
 class ExpressWorker extends ClusterWorker<WorkerData, WorkerResponse> {
   private static server: Server
 
-  private static readonly factorial = (n: number): number => {
-    if (n === 0) {
-      return 1
+  private static readonly factorial = (n: number | bigint): bigint => {
+    if (n === 0 || n === 1) {
+      return 1n
+    } else {
+      n = BigInt(n)
+      let factorial = 1n
+      for (let i = 1n; i <= n; i++) {
+        factorial *= i
+      }
+      return factorial
     }
-    return ExpressWorker.factorial(n - 1) * n
   }
 
   private static readonly startExpress = (
@@ -32,7 +38,9 @@ class ExpressWorker extends ClusterWorker<WorkerData, WorkerResponse> {
 
     application.get('/api/factorial/:number', (req: Request, res: Response) => {
       const { number } = req.params
-      res.send({ number: ExpressWorker.factorial(parseInt(number)) }).end()
+      res
+        .send({ number: ExpressWorker.factorial(parseInt(number)).toString() })
+        .end()
     })
 
     ExpressWorker.server = application.listen(port, () => {
index a478e731b41fd1e529f7e5eb7c549822a12f0a97..9b1df361eca500160506ae09fada8aa53c0845d2 100644 (file)
@@ -15,7 +15,7 @@
     "start:esm": "node --enable-source-maps dist/main.js",
     "test": "echo \"Error: no test specified\" && exit 1",
     "benchmark:echo": "autocannon -c 100 -d 30 -p 10 -m POST -H Content-Type=application/json -b '{\"key1\":\"value1\", \"key2\":\"value2\"}' http://localhost:8080/api/echo",
-    "benchmark:factorial": "autocannon -c 100 -d 30 -p 10 http://localhost:8080/api/factorial/30"
+    "benchmark:factorial": "autocannon -c 100 -d 30 -p 10 http://localhost:8080/api/factorial/50000"
   },
   "keywords": [],
   "author": "",
index d769c762cc24a86999576290199b39dcb436ba5d..b7ff8b166e40bc19d55dfadcf6038f15554cbb8d 100644 (file)
@@ -10,11 +10,17 @@ class RequestHandlerWorker<
   Data extends ThreadWorkerData<DataPayload>,
   Response extends ThreadWorkerResponse<DataPayload>
 > extends ThreadWorker<Data, Response> {
-  private static readonly factorial = (n: number): number => {
-    if (n === 0) {
-      return 1
+  private static readonly factorial = (n: number | bigint): bigint => {
+    if (n === 0 || n === 1) {
+      return 1n
+    } else {
+      n = BigInt(n)
+      let factorial = 1n
+      for (let i = 1n; i <= n; i++) {
+        factorial *= i
+      }
+      return factorial
     }
-    return RequestHandlerWorker.factorial(n - 1) * n
   }
 
   public constructor () {
@@ -25,7 +31,9 @@ class RequestHandlerWorker<
       factorial: (workerData?: Data) => {
         return {
           data: {
-            number: RequestHandlerWorker.factorial(workerData!.data.number!)
+            number: RequestHandlerWorker.factorial(
+              workerData!.data.number!
+            ).toString()
           }
         } as unknown as Response
       }
index c51231f085d02b3576de41545ae1ed7a4b41cc5b..de54766a93c3b6df6f9058709d087832391a8a4b 100644 (file)
@@ -15,7 +15,7 @@
     "start": "node --enable-source-maps dist/main.js",
     "test": "echo \"Error: no test specified\" && exit 1",
     "benchmark:echo": "autocannon -c 100 -d 30 -p 10 -m POST -H Content-Type=application/json -b '{\"key1\":\"value1\", \"key2\":\"value2\"}' http://localhost:8080/api/echo",
-    "benchmark:factorial": "autocannon -c 100 -d 30 -p 10 http://localhost:8080/api/factorial/30"
+    "benchmark:factorial": "autocannon -c 100 -d 30 -p 10 http://localhost:8080/api/factorial/50000"
   },
   "keywords": [],
   "author": "",
index c7a64055cd66b427ac877002b35329afdaaa0737..18e5c8a3cef5aef91512f609f30595c315c6b47c 100644 (file)
@@ -10,11 +10,17 @@ class RequestHandlerWorker<
   Data extends WorkerData<BodyPayload>,
   Response extends WorkerResponse<BodyPayload>
 > extends ThreadWorker<Data, Response> {
-  private static readonly factorial: (n: number) => number = n => {
-    if (n === 0) {
-      return 1
+  private static readonly factorial: (n: number | bigint) => bigint = n => {
+    if (n === 0 || n === 1) {
+      return 1n
+    } else {
+      n = BigInt(n)
+      let factorial = 1n
+      for (let i = 1n; i <= n; i++) {
+        factorial *= i
+      }
+      return factorial
     }
-    return RequestHandlerWorker.factorial(n - 1) * n
   }
 
   public constructor () {
@@ -25,7 +31,9 @@ class RequestHandlerWorker<
       factorial: (workerData?: Data) => {
         return {
           body: {
-            number: RequestHandlerWorker.factorial(workerData!.body.number!)
+            number: RequestHandlerWorker.factorial(
+              workerData!.body.number!
+            ).toString()
           }
         } as unknown as Response
       }
index f7192eefb39a83f965e9e4710082f46456baf990..240a054a2a77fca374c8b4732b7a62784d860fdf 100644 (file)
@@ -15,7 +15,7 @@
     "start:esm": "node --enable-source-maps dist/main.js",
     "test": "echo \"Error: no test specified\" && exit 1",
     "benchmark:echo": "autocannon -c 100 -d 30 -p 10 -m POST -H Content-Type=application/json -b '{\"key1\":\"value1\", \"key2\":\"value2\"}' http://localhost:8080/api/echo",
-    "benchmark:factorial": "autocannon -c 100 -d 30 -p 10 http://localhost:8080/api/factorial/30"
+    "benchmark:factorial": "autocannon -c 100 -d 30 -p 10 http://localhost:8080/api/factorial/50000"
   },
   "keywords": [],
   "author": "",
index 8f4442ed748d3fd2abc62c108d361aa6f565d2e6..e491fa8f4b05c3ee4712740e1e669a102775108e 100644 (file)
@@ -8,11 +8,17 @@ import type { WorkerData, WorkerResponse } from './types.js'
 class FastifyWorker extends ClusterWorker<WorkerData, WorkerResponse> {
   private static fastify: FastifyInstance
 
-  private static readonly factorial = (n: number): number => {
-    if (n === 0) {
-      return 1
+  private static readonly factorial = (n: number | bigint): bigint => {
+    if (n === 0 || n === 1) {
+      return 1n
+    } else {
+      n = BigInt(n)
+      let factorial = 1n
+      for (let i = 1n; i <= n; i++) {
+        factorial *= i
+      }
+      return factorial
     }
-    return FastifyWorker.factorial(n - 1) * n
   }
 
   private static readonly startFastify = async (
@@ -32,7 +38,7 @@ class FastifyWorker extends ClusterWorker<WorkerData, WorkerResponse> {
       Params: { number: number }
     }>('/api/factorial/:number', request => {
       const { number } = request.params
-      return { number: FastifyWorker.factorial(number) }
+      return { number: FastifyWorker.factorial(number).toString() }
     })
 
     await FastifyWorker.fastify.listen({ port })
index 75f6b32905974956b7a82ce90c36bf9cb2f4bbff..785887e43202e142f6f0d065b56b58cfbff4d0ef 100644 (file)
@@ -15,7 +15,7 @@
     "start:esm": "node --enable-source-maps dist/main.js",
     "test": "echo \"Error: no test specified\" && exit 1",
     "benchmark:echo": "autocannon -c 100 -d 30 -p 10 -m POST -H Content-Type=application/json -b '{\"key1\":\"value1\", \"key2\":\"value2\"}' http://localhost:8080/api/echo",
-    "benchmark:factorial": "autocannon -c 100 -d 30 -p 10 http://localhost:8080/api/factorial/30"
+    "benchmark:factorial": "autocannon -c 100 -d 30 -p 10 http://localhost:8080/api/factorial/50000"
   },
   "keywords": [],
   "author": "",
index d769c762cc24a86999576290199b39dcb436ba5d..b7ff8b166e40bc19d55dfadcf6038f15554cbb8d 100644 (file)
@@ -10,11 +10,17 @@ class RequestHandlerWorker<
   Data extends ThreadWorkerData<DataPayload>,
   Response extends ThreadWorkerResponse<DataPayload>
 > extends ThreadWorker<Data, Response> {
-  private static readonly factorial = (n: number): number => {
-    if (n === 0) {
-      return 1
+  private static readonly factorial = (n: number | bigint): bigint => {
+    if (n === 0 || n === 1) {
+      return 1n
+    } else {
+      n = BigInt(n)
+      let factorial = 1n
+      for (let i = 1n; i <= n; i++) {
+        factorial *= i
+      }
+      return factorial
     }
-    return RequestHandlerWorker.factorial(n - 1) * n
   }
 
   public constructor () {
@@ -25,7 +31,9 @@ class RequestHandlerWorker<
       factorial: (workerData?: Data) => {
         return {
           data: {
-            number: RequestHandlerWorker.factorial(workerData!.data.number!)
+            number: RequestHandlerWorker.factorial(
+              workerData!.data.number!
+            ).toString()
           }
         } as unknown as Response
       }
index a3c76a71831288f2ecb6841f0cc0ac00af3b5098..6f7c35a2f823c51d339cdc33607b523cb71a7755 100644 (file)
@@ -15,7 +15,7 @@
     "start": "node --enable-source-maps dist/main.js",
     "test": "echo \"Error: no test specified\" && exit 1",
     "benchmark:echo": "autocannon -c 100 -d 30 -p 10 -m POST -H Content-Type=application/json -b '{\"key1\":\"value1\", \"key2\":\"value2\"}' http://localhost:8080/api/echo",
-    "benchmark:factorial": "autocannon -c 100 -d 30 -p 10 http://localhost:8080/api/factorial/30"
+    "benchmark:factorial": "autocannon -c 100 -d 30 -p 10 http://localhost:8080/api/factorial/50000"
   },
   "keywords": [],
   "author": "",
index c7a64055cd66b427ac877002b35329afdaaa0737..18e5c8a3cef5aef91512f609f30595c315c6b47c 100644 (file)
@@ -10,11 +10,17 @@ class RequestHandlerWorker<
   Data extends WorkerData<BodyPayload>,
   Response extends WorkerResponse<BodyPayload>
 > extends ThreadWorker<Data, Response> {
-  private static readonly factorial: (n: number) => number = n => {
-    if (n === 0) {
-      return 1
+  private static readonly factorial: (n: number | bigint) => bigint = n => {
+    if (n === 0 || n === 1) {
+      return 1n
+    } else {
+      n = BigInt(n)
+      let factorial = 1n
+      for (let i = 1n; i <= n; i++) {
+        factorial *= i
+      }
+      return factorial
     }
-    return RequestHandlerWorker.factorial(n - 1) * n
   }
 
   public constructor () {
@@ -25,7 +31,9 @@ class RequestHandlerWorker<
       factorial: (workerData?: Data) => {
         return {
           body: {
-            number: RequestHandlerWorker.factorial(workerData!.body.number!)
+            number: RequestHandlerWorker.factorial(
+              workerData!.body.number!
+            ).toString()
           }
         } as unknown as Response
       }
index 1f302a6cc76a01bfa6ede514140e9b401af50bc3..9beb2b7828b077eb5fc00c5ce810b3dd7b148d82 100644 (file)
@@ -12,7 +12,7 @@ ws.on('open', () => {
     )
   }
   for (let i = 0; i < 60; i++) {
-    ws.send(JSON.stringify({ type: 'factorial', data: { number: 30 } }))
+    ws.send(JSON.stringify({ type: 'factorial', data: { number: 50000 } }))
   }
 })
 
index 9ec81eb5db8b8c8fc5b7b5d4ad94d522629df89c..232382f609977568a783a5f779300ab86d111567 100644 (file)
@@ -12,11 +12,17 @@ import {
 class WebSocketServerWorker extends ClusterWorker<WorkerData, WorkerResponse> {
   private static wss: WebSocketServer
 
-  private static readonly factorial = (n: number): number => {
-    if (n === 0) {
-      return 1
+  private static readonly factorial = (n: number | bigint): bigint => {
+    if (n === 0 || n === 1) {
+      return 1n
+    } else {
+      n = BigInt(n)
+      let factorial = 1n
+      for (let i = 1n; i <= n; i++) {
+        factorial *= i
+      }
+      return factorial
     }
-    return WebSocketServerWorker.factorial(n - 1) * n
   }
 
   private static readonly startWebSocketServer = (
@@ -48,12 +54,15 @@ class WebSocketServerWorker extends ClusterWorker<WorkerData, WorkerResponse> {
             break
           case MessageType.factorial:
             ws.send(
-              JSON.stringify({
-                type: MessageType.factorial,
-                data: {
-                  number: WebSocketServerWorker.factorial(data.number!)
-                }
-              })
+              JSON.stringify(
+                {
+                  type: MessageType.factorial,
+                  data: {
+                    number: WebSocketServerWorker.factorial(data.number!)
+                  }
+                },
+                (_, v) => (typeof v === 'bigint' ? v.toString() : v)
+              )
             )
             break
         }
index 1f302a6cc76a01bfa6ede514140e9b401af50bc3..9beb2b7828b077eb5fc00c5ce810b3dd7b148d82 100644 (file)
@@ -12,7 +12,7 @@ ws.on('open', () => {
     )
   }
   for (let i = 0; i < 60; i++) {
-    ws.send(JSON.stringify({ type: 'factorial', data: { number: 30 } }))
+    ws.send(JSON.stringify({ type: 'factorial', data: { number: 50000 } }))
   }
 })
 
index d769c762cc24a86999576290199b39dcb436ba5d..004dd3dbc6fcded778bf88b2c156b8d1184f61ef 100644 (file)
@@ -10,11 +10,17 @@ class RequestHandlerWorker<
   Data extends ThreadWorkerData<DataPayload>,
   Response extends ThreadWorkerResponse<DataPayload>
 > extends ThreadWorker<Data, Response> {
-  private static readonly factorial = (n: number): number => {
-    if (n === 0) {
-      return 1
+  private static readonly factorial = (n: number | bigint): bigint => {
+    if (n === 0 || n === 1) {
+      return 1n
+    } else {
+      n = BigInt(n)
+      let factorial = 1n
+      for (let i = 1n; i <= n; i++) {
+        factorial *= i
+      }
+      return factorial
     }
-    return RequestHandlerWorker.factorial(n - 1) * n
   }
 
   public constructor () {
index eabf72ebb30449aaec103e485d8d1105d3bca333..e52f0c06c9331ee011b17b75c8724974c8329a3b 100644 (file)
@@ -78,10 +78,13 @@ ClusterWorkerResponse
               .execute({ data }, 'factorial')
               .then(response => {
                 ws.send(
-                  JSON.stringify({
-                    type: MessageType.factorial,
-                    data: response.data
-                  })
+                  JSON.stringify(
+                    {
+                      type: MessageType.factorial,
+                      data: response.data
+                    },
+                    (_, v) => (typeof v === 'bigint' ? v.toString() : v)
+                  )
                 )
                 return undefined
               })
index 1f302a6cc76a01bfa6ede514140e9b401af50bc3..9beb2b7828b077eb5fc00c5ce810b3dd7b148d82 100644 (file)
@@ -12,7 +12,7 @@ ws.on('open', () => {
     )
   }
   for (let i = 0; i < 60; i++) {
-    ws.send(JSON.stringify({ type: 'factorial', data: { number: 30 } }))
+    ws.send(JSON.stringify({ type: 'factorial', data: { number: 50000 } }))
   }
 })
 
index f3aea4e5b60a2cdc15fa2f3a124ed93673b39b53..7a162499d8f91417246fe1b94289b62083ec584d 100644 (file)
@@ -41,10 +41,13 @@ wss.on('connection', ws => {
           .execute({ data }, 'factorial')
           .then(response => {
             ws.send(
-              JSON.stringify({
-                type: MessageType.factorial,
-                data: response.data
-              })
+              JSON.stringify(
+                {
+                  type: MessageType.factorial,
+                  data: response.data
+                },
+                (_, v) => (typeof v === 'bigint' ? v.toString() : v)
+              )
             )
             return undefined
           })
index 5aa9e90a54fc191ef2453ab94d9cc15639c5cc63..e1b67193a2e944de72ef04e16871793eefa646b7 100644 (file)
@@ -10,11 +10,17 @@ class RequestHandlerWorker<
   Data extends WorkerData<DataPayload>,
   Response extends WorkerResponse<DataPayload>
 > extends ThreadWorker<Data, Response> {
-  private static readonly factorial = (n: number): number => {
-    if (n === 0) {
-      return 1
+  private static readonly factorial = (n: number | bigint): bigint => {
+    if (n === 0 || n === 1) {
+      return 1n
+    } else {
+      n = BigInt(n)
+      let factorial = 1n
+      for (let i = 1n; i <= n; i++) {
+        factorial *= i
+      }
+      return factorial
     }
-    return RequestHandlerWorker.factorial(n - 1) * n
   }
 
   public constructor () {
index 09df7318b44bfb1895331904bc9848f1cddb07ad..a60d95fa82accd3085c2dc352d6e89f60c6db304 100644 (file)
@@ -24,7 +24,7 @@ describe('Dynamic cluster pool test suite', () => {
     let result = await pool.execute({
       function: TaskFunctions.fibonacci
     })
-    expect(result).toBe(75025)
+    expect(result).toBe(354224848179262000000)
     result = await pool.execute({
       function: TaskFunctions.factorial
     })
index fa609cf357a8ac6763f2848c2102a5a47ffd6a0c..794da1c04ccad4dae92b30f0c66c717734d39629 100644 (file)
@@ -68,7 +68,7 @@ describe('Fixed cluster pool test suite', () => {
     let result = await pool.execute({
       function: TaskFunctions.fibonacci
     })
-    expect(result).toBe(75025)
+    expect(result).toBe(354224848179262000000)
     result = await pool.execute({
       function: TaskFunctions.factorial
     })
index 6f563f520989246cdd17198518e178dec1052384..6cefa0aad2486726fa7e25e9093aa200c7bc7f97 100644 (file)
@@ -24,7 +24,7 @@ describe('Dynamic thread pool test suite', () => {
     let result = await pool.execute({
       function: TaskFunctions.fibonacci
     })
-    expect(result).toBe(75025)
+    expect(result).toBe(354224848179262000000)
     result = await pool.execute({
       function: TaskFunctions.factorial
     })
index 3e10a92d0be8156f4dfd22289a0d3197a532fb1b..48f19e4d0f3fae3e586242517a172da199675b5b 100644 (file)
@@ -68,7 +68,7 @@ describe('Fixed thread pool test suite', () => {
     let result = await pool.execute({
       function: TaskFunctions.fibonacci
     })
-    expect(result).toBe(75025)
+    expect(result).toBe(354224848179262000000)
     result = await pool.execute({
       function: TaskFunctions.factorial
     })
index 735d406af1a91d7bb02625bc58bebd56a1c94a6a..4448eaf6a1b79539bc5b717c6f22704092d3102c 100644 (file)
@@ -66,25 +66,34 @@ const jsonIntegerSerialization = n => {
 }
 
 /**
- * Intentionally inefficient implementation.
  * @param {number} n - The number of fibonacci numbers to generate.
  * @returns {number} - The nth fibonacci number.
  */
 const fibonacci = n => {
-  if (n <= 1) return n
-  return fibonacci(n - 1) + fibonacci(n - 2)
+  let current = 1
+  let previous = 0
+  while (--n) {
+    const tmp = current
+    current += previous
+    previous = tmp
+  }
+  return current
 }
 
 /**
- * Intentionally inefficient implementation.
  * @param {number} n - The number to calculate the factorial of.
  * @returns {number} - The factorial of n.
  */
 const factorial = n => {
-  if (n === 0) {
+  if (n === 0 || n === 1) {
     return 1
+  } else {
+    let factorial = 1
+    for (let i = 1; i <= n; i++) {
+      factorial *= i
+    }
+    return factorial
   }
-  return factorial(n - 1) * n
 }
 
 const executeTaskFunction = data => {
@@ -92,7 +101,7 @@ const executeTaskFunction = data => {
     case TaskFunctions.jsonIntegerSerialization:
       return jsonIntegerSerialization(data.n || 100)
     case TaskFunctions.fibonacci:
-      return fibonacci(data.n || 25)
+      return fibonacci(data.n || 100)
     case TaskFunctions.factorial:
       return factorial(data.n || 100)
     default: