Time of execution SD card

Hi every one!

I will try to be as clear as possible.

I am trying to analyze the execution time of the arduino MKR zero for writing increasing number of data into fi les in a SD card. At each iteration of a for loop (where N is ranging from 10 to 1600 with a step size of 10) a fi le is opened, the current date and time are computed and written. Then "1023 1023" is printed N times into the opened file. Finally the fi le is closed and the next file name is found.

Here is my code:

#define TRANSMISSIONSPEED 115200
#include <SPI.h>
#include <SD.h>
//#include "SdFat.h"
//SdFat SD;

#define FILENAMELEN        25               // max filename length
#define FILE_BASE_NAME "Data"
#include <RTCZero.h>
#include <Arduino.h>

const int chipSelect = SS1;
const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1;
const byte seconds = 50;
const byte minutes = 17;
const byte hours   = 15;

const byte day   = 29;
const byte month = 12;
const byte year  = 17;


char fileName[13] = FILE_BASE_NAME "0000.csv";
int N, j;
long t1, t2, t3, t4, t5, t6, t7;
String CurrentDate, CurrentTime;
File file;
RTCZero rtc;

//------------------------------------------------------------------------------

String getDate(void) {
  int MyDay = rtc.getDay(), MyMonth = rtc.getMonth(), MyYear = rtc.getYear();
  String returnString = "";

  if (MyDay < 10)
    returnString += "0" + String(MyDay);
  else
    returnString += String(MyDay);

  returnString += "/";

  if (MyMonth < 10)
    returnString += "0" + String(MyMonth);
  else
    returnString += String(MyMonth);

  returnString += "/";
  returnString += String(MyYear);

  return returnString;
}

//------------------------------------------------------------------------------

String getTime(void) {
  int MyHours = rtc.getHours(), MyMinutes = rtc.getMinutes(), MySeconds = rtc.getSeconds();
  String returnString = "";

  if (MyHours < 10)
    returnString += "0" + String(MyHours);
  else
    returnString += String(MyHours);

  returnString += ":";

  if (MyMinutes < 10)
    returnString += "0" + String(MyMinutes);
  else
    returnString += String(MyMinutes);

  returnString += ":";

  if (MySeconds < 10)
    returnString += "0" + String(MySeconds);
  else
    returnString += String(MySeconds);

  return returnString;
}

//------------------------------------------------------------------------------

void NextFileName() {
  if (fileName[BASE_NAME_SIZE + 3] != '9') {
    fileName[BASE_NAME_SIZE + 3]++;
  }
  else if (fileName[BASE_NAME_SIZE + 2] != '9') {
    fileName[BASE_NAME_SIZE + 3] = '0';
    fileName[BASE_NAME_SIZE + 2]++;
  }
  else if (fileName[BASE_NAME_SIZE + 1] != '9') {
    fileName[BASE_NAME_SIZE + 3] = '0';
    fileName[BASE_NAME_SIZE + 2] = '0';
    fileName[BASE_NAME_SIZE + 1]++;
  }
  else if (fileName[BASE_NAME_SIZE] != '9') {
    fileName[BASE_NAME_SIZE + 3] = '0';
    fileName[BASE_NAME_SIZE + 2] = '0';
    fileName[BASE_NAME_SIZE + 1] = '0';
    fileName[BASE_NAME_SIZE]++;
  }
  else {
    Serial.println(F("Can't create new file name"));
  }
}

//------------------------------------------------------------------------------

void setup()
{ 
  Serial.begin(TRANSMISSIONSPEED);
  delay(7000);
  Serial.println("program start");

  rtc.begin();
  rtc.setTime(hours, minutes, seconds);
  rtc.setDate(day, month, year);
  Serial.println("RTC initialized");

  Serial.println("SD card initialization.");
  if (!SD.begin(SS1)) {
    Serial.println("SD card initialization failed!");
    return;
  }
  Serial.println("SD card initialization done.");

int BorneInferieure, BorneSuperieure, Milieu;
  Serial.begin(TRANSMISSIONSPEED);
  delay(7000);
  Serial.println("program start");

  Serial.println("SD card initialization.");
  if (!SD.begin(SS1)) {
    Serial.println("SD card initialization failed!");
    return;
  }
  Serial.println("SD card initialization done.");

 //Binary search of the first file name

  BorneInferieure = 0;
  BorneSuperieure = 9999;
  while (BorneSuperieure - BorneInferieure > 1)
  {
    Milieu = (BorneInferieure + BorneSuperieure) / 2; 
    Serial.print(BorneInferieure);Serial.print("/"); Serial.print(Milieu); Serial.print("/"); Serial.print(BorneSuperieure);
    fileName[BASE_NAME_SIZE    ] = 48 + (Milieu / 1000);
    fileName[BASE_NAME_SIZE + 1] = 48 + (Milieu / 100) % 10;
    fileName[BASE_NAME_SIZE + 2] = 48 + (Milieu / 10) % 10;
    fileName[BASE_NAME_SIZE + 3] = 48 + (Milieu % 10);
    Serial.print(" Le fichier "); Serial.print(fileName);
    if (SD.exists(fileName))
    {
      BorneInferieure = Milieu;
      Serial.println(" existe");
    }
    else
    {
      BorneSuperieure = Milieu;
      Serial.println(" n'existe pas");
    }
    
  }
  if (SD.exists(fileName))
  {
    NextFileName();
    Serial.print("Le Fichier final est "); Serial.println(fileName);
  }
  else
  {
    Serial.print("Le Fichier final est "); Serial.println(fileName);
  }
}


//------------------------------------------------------------------------------

void loop() {
  for (N = 10; N <= 1600; N = N + 10) {
    //Serial.print(F("File used: ")); Serial.println(fileName);
    t1 = micros();
    file = SD.open(fileName, FILE_WRITE);
    t2 = micros();

   if (file) {
      CurrentDate = getDate();
      CurrentTime = getTime();
      t3 = micros();
      file.println("Date: " + CurrentDate);
      file.println("Time: " + CurrentTime);
      t4 = micros();

      for (j = 0; j < N; j++)
      {
        file.print(1023); file.print(" "); file.println(1023); // voltage and current
      }
      t5 = micros();
      file.close();
      t6 = micros();
      NextFileName();
    }
   else {
  Serial.println("error opening file");    // if the file didn't open, print an error:
  }
    t7 = micros();

    Serial.print(N); Serial.print(";"); 
    Serial.print(t7 - t1); Serial.print(";");
    Serial.print(t2 - t1); Serial.print(";");
    Serial.print(t3 - t2); Serial.print(";");
    Serial.print(t4 - t3); Serial.print(";");
    Serial.print(t5 - t4); Serial.print(";");
    Serial.print(t6 - t5); Serial.print(";");
    Serial.println(t7 - t6); 
  }
}

Attached, the figure that I obtain when plotting execution times vs number of datas.

I was expecting to have a "straight line passing through the origine". However, it is not the case and the obtained plot exhibits spikes which stand out at random values of N and with random execution times. Split elapsed times are computed in order to understand such a shape.
The pink plot denotes the needed time to open a le at each iteration using the "SD.open();"
function. The more files we create, the longer "SD.open();" needs to check if the file is already
created or not, then create it. Is it normal?
The light blue plot depicts the needed time to get the date and the time using the "getDate();"
and "getTime();" functions. At each iteration, it takes the same time to get the date and time
and almost the same time to print it into a file (red plot), a disruption is however observed.
The green plot shows the needed time to close a fi le.
The yellow plot which correspond to a constant line represents the time required to fi nd the
next file name once the file is closed. The required time is negligible (3 micro seconds). The blue plots corresponds to the time required to print into a file a number of N data. Most of the spikes in the black plot are retrieved. In order to understand the origine of such spikes, I looked into the content of the files for which the plot shows spikes: the needed time to print into files doesn't affect their expected content (these spikes are not corrupting the data).

Can somebody please explain these phenomena?
Any help will be appreciated. Thanks.

executiontime-data profile.JPG