Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🚧Increase fps calc perf #1077

Closed
7 tasks done
CalvinWilkinson opened this issue Jan 19, 2025 · 0 comments · Fixed by #1078
Closed
7 tasks done

🚧Increase fps calc perf #1077

CalvinWilkinson opened this issue Jan 19, 2025 · 0 comments · Fixed by #1078
Assignees
Labels
medium-priority Medium Priority 🏎️performance Performance improvements preview Done while in preview

Comments

@CalvinWilkinson
Copy link
Member

CalvinWilkinson commented Jan 19, 2025

Complete The Item Below

  • I have updated the title without removing the 🚧 emoji.

Description

Increase the performance of the TimeService, which is used to calculate a game's FPS(Frames Per Sec).

This will involve the current implementation

// <copyright file="TimerService.cs" company="KinsonDigital">
// Copyright (c) KinsonDigital. All rights reserved.
// </copyright>

namespace Velaptor.Services;

using System;
using System.Runtime.CompilerServices;

/// <inheritdoc/>
internal sealed class TimerService : ITimerService
{
    private const int SAMPLE_SIZE = 1000;
    private readonly IStopWatchWrapper stopWatch;
    private readonly double[] timeSamples = new double[SAMPLE_SIZE];
    private readonly double tickFreqMs;
    private double runningSum;
    private long startTicks;
    private long stopTicks;
    private int index;
    private bool isArrayFull;
    private int divisor;

    /// <summary>
    /// Initializes a new instance of the <see cref="TimerService"/> class.
    /// </summary>
    /// <param name="stopWatch">Tracks and measures time passed.</param>
    public TimerService(IStopWatchWrapper stopWatch)
    {
        this.stopWatch = stopWatch;
        this.tickFreqMs = 1000.0 / this.stopWatch.Frequency;
    }

    /// <inheritdoc/>
    /// <remarks>This is averaged over 1000 samples.</remarks>
    public float MillisecondsPassed { get; private set; }

    /// <inheritdoc/>
    public void Start() => this.startTicks = this.stopWatch.GetTimestamp();

    /// <inheritdoc/>
    public void Stop()
    {
        this.stopTicks = this.stopWatch.GetTimestamp();
        var sample = (this.stopTicks - this.startTicks) * this.tickFreqMs;
        AddSample(sample);

        // Set the divisor to avoid division by zero and to divide by the correct number of samples
        // which is important for calculating the average
        this.divisor = this.index == 1 ? 1 : this.index;

        // Calculate average using running sum
        MillisecondsPassed = (float)(this.runningSum / (this.isArrayFull ? SAMPLE_SIZE : this.divisor));
    }

    /// <inheritdoc/>
    public void Reset()
    {
        this.index = 0;
        this.runningSum = 0;
        this.isArrayFull = false;
        Array.Clear(this.timeSamples, 0, SAMPLE_SIZE);
        MillisecondsPassed = 0;
    }

    /// <summary>
    /// Adds the given <paramref name="sample"/> to the list of samples.
    /// </summary>
    /// <param name="sample">The sample to add.</param>
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    private void AddSample(double sample)
    {
        // Subtract the old value from running sum before replacing it
        this.runningSum -= this.timeSamples[this.index];
        this.runningSum += sample;
        this.timeSamples[this.index] = sample;

        if (this.index == SAMPLE_SIZE - 1)
        {
            this.isArrayFull = true;
        }

        this.index = this.index >= this.timeSamples.Length - 1
            ? 0
            : this.index + 1;
    }
}

This will also require changes to the IStopWatchWrapper interface and StopWatchWrapper class implementation. We do not need any of the current methods used. The only method we need to wrap now is the GetTimestamp() method.

Do the following:

  1. Remove all of the current props and methods in the stopwatch wrapper types
  2. Implement the GetTimestamp() method, which is the only method needed.
  3. Update the TimerService implementation to the code above.
  4. Make sure the new implementation works correctly with FPS numbers comparable to the old one.
  5. Update the unit tests for the TimerService

Acceptance Criteria

The items to complete to satisfy the Definition of Done.

Preview Give feedback

ToDo Items

The items to complete to satisfy the Definition of Done.

Preview Give feedback

Issue Dependencies

No response

Related Work

No response

Additional Information:

Unit Tests

Reasons for local unit test execution:

  • Unit tests might pass locally but not in the CI environment during the status check process or vice-versa.
  • Tests might pass on the developer's machine but not necessarily on the code reviewer's machine.
  • If you notice that the test status check has passed but the test failed locally, please notify a project maintainer!

💡Warning💡
If the unit tests pass remotely and are not executed locally, this means we could be letting a bug slip into production.
Though bugs will always exist in some capacity, we should all do our part to help prevent them from happening.

Change Type Labels

Change Type Label
Bug Fixes 🐛bug
Breaking Changes 🧨breaking-changes
New Feature ✨new-feature
CICD Changes ♻️cicd
Config Changes ⚙️config
Performance Improvements 🏎️performance
Code Doc Changes 🗒️documentation/code
Product Doc Changes 📝documentation/product

Priority Type Labels

Priority Type Label
Low Priority low priority
Medium Priority medium priority
High Priority high priority

Code of Conduct

  • I agree to follow this project's Code of Conduct.
@CalvinWilkinson CalvinWilkinson added medium-priority Medium Priority preview Done while in preview 🏎️performance Performance improvements 💎enhancement An improvement on something labels Jan 19, 2025
@CalvinWilkinson CalvinWilkinson added this to the v1.0.0-preview.41 milestone Jan 19, 2025
@CalvinWilkinson CalvinWilkinson self-assigned this Jan 19, 2025
@github-project-automation github-project-automation bot moved this to ⚪Not Set in KD-Team Jan 19, 2025
@CalvinWilkinson CalvinWilkinson moved this from ⚪Not Set to 🏗️In Development in KD-Team Jan 19, 2025
CalvinWilkinson added a commit that referenced this issue Jan 19, 2025
@CalvinWilkinson CalvinWilkinson changed the title 🚧Increase perf of calculating 🚧Increase fps calc perf Jan 20, 2025
@CalvinWilkinson CalvinWilkinson removed the 💎enhancement An improvement on something label Jan 21, 2025
CalvinWilkinson added a commit that referenced this issue Jan 21, 2025
* Start work for issue #1077

* perf: improve perf of fps calcs and its accuracy
@github-project-automation github-project-automation bot moved this from 🏗️In Development to ✅Done in KD-Team Jan 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
medium-priority Medium Priority 🏎️performance Performance improvements preview Done while in preview
Projects
Status: ✅Done
Development

Successfully merging a pull request may close this issue.

1 participant