units.ts 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. export function relativeChange(final: number, initial: number): number {
  2. return (final - initial) / initial;
  3. }
  4. type Unit = 'nanoseconds' | 'microseconds' | 'milliseconds' | 'seconds';
  5. const durationMappings: Record<Unit, number> = {
  6. nanoseconds: 1e-9,
  7. microseconds: 1e-6,
  8. milliseconds: 1e-3,
  9. seconds: 1,
  10. };
  11. const format = (v: number, abbrev: string, precision: number) => {
  12. return v.toFixed(precision) + abbrev;
  13. };
  14. export function makeFormatter(from: Unit | string): (value: number) => string {
  15. const multiplier = durationMappings[from];
  16. if (multiplier === undefined) {
  17. throw new Error(`Cannot format from unit ${from}, duration mapping is not defined`);
  18. }
  19. return (value: number) => {
  20. const duration = value * multiplier;
  21. if (duration >= 1) {
  22. return format(duration, 's', 2);
  23. }
  24. if (duration / 1e-3 >= 1) {
  25. return format(duration / 1e-3, 'ms', 2);
  26. }
  27. if (duration / 1e-6 >= 1) {
  28. return format(duration / 1e-6, 'μs', 2);
  29. }
  30. return format(duration / 1e-9, 'ns', 2);
  31. };
  32. }
  33. function pad(n: number, slots: number) {
  34. return Math.floor(n).toString().padStart(slots, '0');
  35. }
  36. export function makeTimelineFormatter(from: Unit | string) {
  37. const multiplier = durationMappings[from];
  38. if (multiplier === undefined) {
  39. throw new Error(`Cannot format from unit ${from}, duration mapping is not defined`);
  40. }
  41. return (value: number) => {
  42. const s = value * multiplier;
  43. const m = s / 60;
  44. const ms = s * 1e3;
  45. return `${pad(m, 2)}:${pad(s % 60, 2)}.${pad(ms % 1e3, 3)}`;
  46. };
  47. }