Hone logo
Hone
Problems

Instrumenting Code for Performance Analysis in Jest

Code instrumentation involves adding code to your application to collect performance data, such as function execution times or memory usage. This challenge focuses on implementing instrumentation within a TypeScript project using Jest to measure the execution time of specific functions. This is crucial for identifying performance bottlenecks and optimizing your code.

Problem Description

You are tasked with instrumenting a simple TypeScript module containing several functions. Your goal is to modify the module to measure and log the execution time of three specific functions: calculateSum, processData, and generateReport. You will use Jest to test that the instrumentation code is present and that the timing logic functions correctly without impacting the core functionality of the module. The instrumentation should log the function name and execution time to the console.

Key Requirements:

  • Instrumentation: Wrap the specified functions with code that records the start and end time of their execution.
  • Timing Logic: Calculate the execution time by subtracting the start time from the end time.
  • Logging: Log the function name and execution time to the console using console.timeLog for clear output.
  • Non-Intrusive: The instrumentation should not alter the core functionality or return values of the original functions.
  • Jest Integration: Write Jest tests to verify that the instrumentation code is present and that the timing logic is working as expected. The tests should not assert specific execution times (as these can vary), but rather confirm that console.timeLog is called with the correct function name.

Expected Behavior:

When the instrumented module's functions are called, the corresponding execution time should be logged to the console using console.timeLog. The Jest tests should pass, confirming the presence and basic functionality of the instrumentation.

Edge Cases to Consider:

  • Functions that call other functions within them. The instrumentation should still capture the total execution time of the instrumented function.
  • Asynchronous operations within the instrumented functions (although this challenge focuses on synchronous functions, consider how you might extend the instrumentation to handle asynchronous code).

Examples

Example 1:

Input:
module.ts:
```typescript
export function calculateSum(a: number, b: number): number {
  return a + b;
}

export function processData(data: number[]): number[] {
  return data.map(x => x * 2);
}

export function generateReport(data: number[]): string {
  const sum = data.reduce((a, b) => a + b, 0);
  return `Report: Sum = ${sum}`;
}
Output (to console when calling the functions):
calculateSum: 0.01ms
processData: 0.02ms
generateReport: 0.03ms

Example 2:

Input: Jest test file
```typescript
import { calculateSum, processData, generateReport } from './module';

jest.spyOn(console, 'timeLog');

describe('Instrumentation Tests', () => {
  it('should log calculateSum execution time', () => {
    calculateSum(1, 2);
    expect(console.timeLog).toHaveBeenCalledWith('calculateSum');
  });

  it('should log processData execution time', () => {
    processData([1, 2, 3]);
    expect(console.timeLog).toHaveBeenCalledWith('processData');
  });

  it('should log generateReport execution time', () => {
    generateReport([1, 2, 3]);
    expect(console.timeLog).toHaveBeenCalledWith('generateReport');
  });
});

Constraints

  • The instrumentation should be implemented using console.timeLog.
  • The module to be instrumented is provided in the module.ts file (see Example 1).
  • The Jest tests should only verify that console.timeLog is called with the correct function name, not the actual execution time.
  • The solution must be written in TypeScript.
  • The solution should not introduce any unnecessary dependencies.

Notes

  • Consider using a higher-order function or a decorator pattern to apply the instrumentation consistently across multiple functions.
  • Remember to start and stop the timer correctly to accurately measure execution time.
  • The jest.spyOn method is useful for mocking and spying on console methods for testing purposes.
  • Focus on the instrumentation logic itself; the correctness of the original functions is assumed.
  • The goal is to demonstrate the ability to add instrumentation code and verify its presence using Jest.
Loading editor...
typescript