How do I fix my "Particle Engine"?

I’m having a problem with creating my own Particle Engine in SDL2. I can’t figure out why it’s really laggy, and even using a debugger like gdb does not help at all. I also tried to double check my particle and particle emitter code, but I can’t find what went wrong. I tried to follow Lazy Foo’s Particle Engine tutorial and made my own implementation. This is made completely using SDL2 and has absolutely no OpenGL code, by the way. Here’s my classes (divided into header and C++ files):

Particle.hpp:

#pragma once

#include "Sprite.hpp"

namespace flux
{
    class Particle
    {
    public:
        Particle();
        virtual ~Particle();

        Particle(const char *spritePath, SDL_Renderer *renderer, float x, float y, float lifetime);

        void RenderParticle();
        bool IsDestroyed();

    private:
        float xPos, yPos;
        float lifetime;
        flux::Sprite *particleSprite;
    };
} // namespace flux

Particle.cpp:

#include "Fluxior/Graphics/Particle.hpp"

namespace flux
{
    Particle::Particle() : particleSprite(nullptr) {}

    Particle::~Particle()
    {
        delete particleSprite;
        particleSprite = nullptr;
    }

    Particle::Particle(const char *spritePath, SDL_Renderer *renderer, float x, float y, float lifetime)
    {
        xPos = x - 5.0f + (rand() % 25);
        yPos = y - 5.0f + (rand() % 25);
        this->lifetime = lifetime;
        particleSprite = new flux::Sprite(spritePath, renderer);
    }

    void Particle::RenderParticle()
    {
        particleSprite->SetPosAndSize(xPos, yPos, particleSprite->GetFrameWidth(), particleSprite->GetFrameHeight());
        particleSprite->RenderSprite();
        lifetime -= 1.0f;
    }

    bool Particle::IsDestroyed()
    {
        return lifetime <= 0.0f;
    }
}

ParticleEmitter.hpp:

#include "Particle.hpp"

namespace flux
{
    class ParticleEmitter
    {
    public:
        ParticleEmitter(float x, float y, int numParticles, float particleLifetime);

        virtual ~ParticleEmitter();

        void EmitParticles(const char *spritePath, SDL_Renderer *renderer);

    private:
        float xPos, yPos;
        int maxParticles;
        float particleLifetime;
        Particle **particles;
    };
} // namespace flux

ParticleEmitter.cpp:

#include "Fluxior/Graphics/ParticleEmitter.hpp"

namespace flux
{
    ParticleEmitter::ParticleEmitter(float x, float y, int numParticles, float particleLifetime)
        : xPos(x), yPos(y), maxParticles(numParticles), particleLifetime(particleLifetime)
    {
        particles = new Particle *[maxParticles];
    }

    ParticleEmitter::~ParticleEmitter()
    {
        for (int i = 0; i < maxParticles; ++i)
        {
            delete particles[i];
        }
        delete[] particles;
    }

    void ParticleEmitter::EmitParticles(const char *spritePath, SDL_Renderer *renderer)
    {
        for (int i = 0; i < maxParticles; ++i)
        {
            particles[i] = new Particle(spritePath, renderer, xPos, yPos, particleLifetime);
        }

        for (int i = 0; i < maxParticles; ++i)
        {
            if (particles[i]->IsDestroyed())
            {
                delete particles[i];
                particles[i] = new Particle(spritePath, renderer, xPos, yPos, particleLifetime);
            }
        }

        for (int i = 0; i < maxParticles; ++i)
        {
            particles[i]->RenderParticle();
        }
    }
} // namespace flux

I know some might tell me that the fault might be on my Sprite class, but since I’ve tested it for creating and rendering sprites, and even sprite sheet animation, it definitely does not have to do anything with it. Surely it’s with my particle code (Still a beginner in this so sorry if all I needed to do was something simple). Thanks in advance to anyone who tries to help.

It’s hard to say anything without a full working example. You can try gprof to find the culprit there.

Well, gprof is only available in Unix-like systems as far as I know. I’m using Windows 11, so that’s not an option for me. Any other suggestions? I’m pretty sure I just have something wrong with my code, but I really can’t find it.

gprof is available for Windows too. You can install MSYS2 to get convenient access to all MinGW’s ports.

While it is possible to find the problem just by looking at your code, it will take a lot of effort. You’d better provide a minimal example so others can check.

Some things I see as a problem, but they may not be the cause of the slowdown:

What’s the point of this? new Particle[maxParticles]; will work good (but you really should use std::vector here).

This way you delete and allocate particles every time, you don’t use any of dynamic memory features. Your array is statically sized, and you always re-allocate the particle you destroyed. Even if you need a particle to be “empty”, it’s better to use std::optional, which doesn’t introduce any dynamic allocations.

The code is missing many important points, like a Sprite class. You should use a profiler if you want to track “slow” functions, I believe you have one bundled in Visual Studio.

Is EmitParticles called every frame? Unless you use some kind of cache it would be extremely inefficent to load the sprite images for all the particles every frame. If they all use the same image you should ideally only have to load the image once, at the start, and then be able to reuse it for all of the particles.

Well first of all, I use Visual Studio Code. Second, I’m still in the prototyping phase, so I haven’t implemented the modern C++ features (or I guess they’re not modern C++).

I guess that’s the reason why it lags. I’m still just a beginner though, so I don’t know how to adjust the code. In fact, I don’t know everything about what’s happening in the particle system I implemented (pretty much the Particle code is based off of Lazy Foo’s tutorial of the same topic).