Arduino mega 2560 runs slow then fast again

I have a sketch that reads color values from an sdcard then displays these colors on WS2812B LED strip using fastLED library.
I have 350+ files on the sdcard, After reading each file it displays it then closes it then reads the next file, but after reading the first 200 files it starts running slow until it finishes all the files then starts to run fast again.
How can I fix that behavior?

The content of each file is like the following: each row contains the color value(in decimal base) of one LED

0
0
0
15665680
0
0
0
15663120
0
0
0
16194832
0
0
14479120
0
782096
978723
192455
0
1043711
343807
0
1376510
0
13893887
0
0
0
0

The code I use to do all of that

#include <FastLED.h>
#include <SD.h>

#define CHIP_SELECT 53
#define DATA_OUT 51
#define DATA_IN 50
#define CLOCK 52
#define CUBE_PIN 48
#define NUM_LEDS 150

CRGB leds[NUM_LEDS];
File myFile;
//String frames_files=
//void 

void read_files(){
  myFile = SD.open("display");
  if (myFile) {
    while(true){
      FastLED.clear();
      File frame = myFile.openNextFile();
      if(! frame) return;

      int current_led=0;
      int current_led_in_the_row=0;
      String current_color = "";

      while (frame.available()) {
        char chr = frame.read();
        current_color += chr;
        if(chr == '\n'){
          if(current_led_in_the_row==3){
            current_led_in_the_row= 0;
            current_led += 9;
            }

          leds[current_led] = current_color.toInt();
          current_led++;
          current_led_in_the_row++;
          current_color="";
          }
        }
        frame.close();

        FastLED.show();

      }
      myFile.close();
    }
    
}

void setup() {
  FastLED.addLeds<WS2812B, CUBE_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(255);
  SD.begin();
  Serial.begin(115200);

  
  
}

void loop() {
    read_files();
}

Avoid the String type, use char arrays instead.

My guess is you are out of RAM for the file system. Consider combining several in one file as you read them sequentially anyway. If you can simply use an ASCII character, then you know when a new record is reached. This is a starting point.
Good Luck & Have Fun!
Gil

DrDiettrich:
Avoid the String type, use char arrays instead.

I've tried that but the result is the same.

gilshultz:
My guess is you are out of RAM for the file system. Consider combining several in one file as you read them sequentially anyway. If you can simply use an ASCII character, then you know when a new record is reached. This is a starting point.
Good Luck & Have Fun!
Gil

Does running out of memory makes it run slow?
I close every file after finishing reading it. So it should free up memory space.

Does running out of memory makes it run slow?

No.

It normally makes it not run at all, or have strange faults. I think that comment was based on experience of a different processor architecture where you swap memory between different sorts of memory like an SD card and ram. The basic Arduinos do not run from RAM but from flash memory.

Can you post the code where you replaced the String types so we can see how you did it.

Grumpy_Mike:
No.

It normally makes it not run at all, or have strange faults. I think that comment was based on experience of a different processor architecture where you swap memory between different sorts of memory like an SD card and ram. The basic Arduinos do not run from RAM but from flash memory.

Can you post the code where you replaced the String types so we can see how you did it.

I've tried that after @DrDiettrich suggestion. here's the code for this change
note: I've tried @gilshultz suggestion to read multiple frames from one file instead of making separate file for each one and it seems to be working. I still need to test it more, to make sure it's fully working.
you can see the code for it here => LED_cube_display/LED_cube_display.ino at onefile · Lehkeda/LED_cube_display · GitHub

void read_files(){
  int current_led_in_the_face=0;
  myFile = SD.open("colors");
  if (myFile) {
    while(true){
      FastLED.clear();
      File frame = myFile.openNextFile();
      if(! frame) return;
      int current_led=0;
      int current_led_in_the_row=0;
      
      char current_color[10] = "";
      char i=0;
      while (frame.available()) {
        char chr = frame.read();
        current_color[i] = chr;
        if(chr == '\n'){
          if(current_led_in_the_face == 30){
            current_led_in_the_face=99;
            frame.close();
            break;
            }
          if(current_led_in_the_row==3){
            current_led_in_the_row= 0;
            current_led += 9;
            }

          leds[current_led] = atoi(current_color);
          current_led++;
          current_led_in_the_row++;
          current_led_in_the_face++;
          i=0;
          for(int x=0; x<10; x++){
            current_color[i]=0;
          }
          continue;
          }
          i++;
        }
        frame.close();

        if(current_led_in_the_face==99){
          current_led_in_the_face=0;
          continue;
          }
        FastLED.show();

      }
      myFile.close();
    }
    
}

while(true) in any program worries me. Are you sure you are returning to the correct place? It could be that you are not actually closing the file because you are returning out of the loop function not the while. Even if it is OK it is bad practice.

Grumpy_Mike:
while(true) in any program worries me. Are you sure you are returning to the correct place? It could be that you are not actually closing the file because you are returning out of the loop function not the while. Even if it is OK it is bad practice.

I guess this might be it, because when I've changed the way my code works, it works flawlessly

here's the new code

void read_files(){
  frame = SD.open("colors/all.txt");
  if (frame) {
    int color_value_position=0;
    String current_color = "";
    bool skip_next=false;
    int current_led=0;
    int current_led_in_the_row=0;
    
    while (frame.available()){
      char color_value=frame.read();
     
      if(color_value == '\n'){
        if(skip_next){skip_next= false; continue;}
        
        if(current_led_in_the_row==3){
          current_led_in_the_row= 0;
          current_led += 9;
        }

        leds[current_led] = current_color.toInt();
        current_led++;
        current_led_in_the_row++;
        current_color="";
        }else if(color_value == '_'){
          color_value_position=0;
          current_color="";
          current_led_in_the_row= 0;
          current_led = 0;
          skip_next=true;
          FastLED.show();
        }else{
          current_color += color_value;
        }
    } //frame.available()
  } // frame
  frame.close();
}

You do no error handling so why not use binary data files instead of text? You won't have to translate text to binary.

CRGB elements are 3 bytes, 1 each for red, green and blue. Store values, read values and fill the FastLed array then run the show function. That leds[] array is all you want to store anyway.

I'm pretty sure that an Uno could do this.

GoForSmoke:
You do no error handling so why not use binary data files instead of text? You won't have to translate text to binary.

CRGB elements are 3 bytes, 1 each for red, green and blue. Store values, read values and fill the FastLed array then run the show function. That leds[] array is all you want to store anyway.

I'm pretty sure that an Uno could do this.

Actually, I was planning to read these values from .BMP file instead of txt files, but I didn't want to deal with the hassle of reading the BMP file and figuring out how everything fits together. So I have a PHP script that reads the BMP files using ready-to-use-out-of-the-box functions then out put these values in a txt file then read these values using the Arduino.
The reason there's no error handling is that I know the structure and how everything is going to be so everything is running in a controlled environment, Plus I'm still in the prototyping stage so no need to do error handling for now

LehKeda:
Actually, I was planning to read these values from .BMP file instead of txt files, but I didn't want to deal with the hassle of reading the BMP file and figuring out how everything fits together. So I have a PHP script that reads the BMP files using ready-to-use-out-of-the-box functions then out put these values in a txt file then read these values using the Arduino.
The reason there's no error handling is that I know the structure and how everything is going to be so everything is running in a controlled environment, Plus I'm still in the prototyping stage so no need to do error handling for now

Handling involves recovery and that needs structure. If you don't build it in from the start then you end up kludging it in later. I've done the latter often enough to know how it happens.

BMP files are not arcane. They are very step by step, find a good doc on BMP files and it should have a kind of file layout "map". Your read & display speed should jump.

At the very least if you're using text, make it hex values of the binary data and you won't need atoi() to assemble the values into CRGB, 6 bytes per pixel at most will do.