Skip to content

Implements seekDir and getNextFileName on FS Lib to improve performance #7229

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

Merged
merged 3 commits into from
Dec 7, 2022

Conversation

Lucasczm
Copy link
Contributor

@Lucasczm Lucasczm commented Sep 6, 2022

Description of Change

Implemented two functions:

  • getNextFileName: Get the next file name with better performance than getNextFile function. To improve file listing.
  • seekDir: Set the position of directory for improve search.

Examples:

 File root = SD.open("/data");
 String filename;
 //Return true if have next file, false if not
 if (root.getNextFileName(filename)) {
     Serial.println(filename); //print "file1"
 }

Tests scenarios

Tested on PlatformIO and Arduino core v2.0.4 with ESP32 LILYGO PoE Board

Related links

#5002

@CLAassistant
Copy link

CLAassistant commented Sep 6, 2022

CLA assistant check
All committers have signed the CLA.

@Lucasczm Lucasczm force-pushed the master branch 2 times, most recently from 361cfb4 to 1a9c389 Compare September 6, 2022 13:24
@SuGlider SuGlider self-assigned this Sep 6, 2022
@P-R-O-C-H-Y P-R-O-C-H-Y added Type: Feature request Feature request for Arduino ESP32 Area: Libraries Issue is related to Library support. labels Sep 7, 2022
@me-no-dev
Copy link
Member

For getNextFileName why don't you return the filename directly (or empty String if not available) instead?

@PilnyTomas
Copy link
Contributor

Tested using this sketch confirming that the new function is way much faster:
new function ~0.24ms per folder read
old function openNextFile ~142ms per folder read

Copy link
Contributor

@PilnyTomas PilnyTomas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apart from the requested changes looks good.

Copy link
Contributor Author

@Lucasczm Lucasczm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now its return String name directly or String empty

@tueddy
Copy link
Contributor

tueddy commented Sep 24, 2022

The speed improvement is amazing! For a webserver SD filexplorer the time for listing is currently about 2 seconds (very blocking), with this PR only 20 msecs (hundreds of mp3 files on SD card). Works fine here!

But for the Javascript based file explorer tree i also need the information wether it's a file or directory. Is there a way to get it?
Suggestion: add a trailing slash in filename if it's a directory or add an overload function with out-param isDirectory.

`

String VFSFileImpl::getNextFileName()
{
...
name += fname;
// add trailing slash for detecting directory
if (file->d_type == DT_DIR) {
name = "/" + name;
}
return name;
}

`

Thank's!

@Lucasczm Lucasczm requested review from SuGlider and me-no-dev and removed request for P-R-O-C-H-Y, SuGlider and me-no-dev September 25, 2022 00:42
@tueddy
Copy link
Contributor

tueddy commented Oct 7, 2022

I made a speedtest example for PIO here https://github.com/tueddy/FS/tree/main/example
Tested my SD-cards with a lot of files in root directory:

Samsung Evo 32GB:
getNextFileName(), done reading root-directory 36 elemts in 18 ms = 0.50 ms/folder
openNextFile(), done reading root-directory 36 elements in 492 ms = 13.67 ms/elements

Kingston 8GB, a bit older card:
getNextFileName(), done reading root-directory 42 elemts in 29 ms = 0.69 ms/folder
openNextFile(), done reading root-directory 42 elements in 1119 ms = 26.64 ms/elements

Transcend 16GB:
getNextFileName(), done reading root-directory 84 elemts in 83 ms = 0.99 ms/folder
openNextFile(), done reading root-directory 84 elements in 6960 ms = 82.86 ms/elements

Scandisk 16GB:
getNextFileName(), done reading root-directory 151 elemts in 68 ms = 0.45 ms/folder
openNextFile(), done reading root-directory 151 elements in 6872 ms = 45.51 ms/elements

@Lucasczm Lucasczm requested review from me-no-dev and removed request for SuGlider October 26, 2022 20:11
@me-no-dev
Copy link
Member

@SuGlider waiting on your approval here :)

Copy link
Contributor

@vortigont vortigont left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a small hint for String's

@Lucasczm Lucasczm requested a review from SuGlider November 4, 2022 13:20
@VojtechBartoska VojtechBartoska added this to the 2.0.6 milestone Nov 7, 2022
Copy link
Collaborator

@SuGlider SuGlider left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Lucasczm - Thanks for the PR! Very good.

@SuGlider
Copy link
Collaborator

SuGlider commented Dec 7, 2022

@Lucasczm - I can't rebase it from here. Please do it in your end in order to be able to merge it. Thanks.

@SuGlider SuGlider added the Resolution: Awaiting response Waiting for response of author label Dec 7, 2022
@Lucasczm
Copy link
Contributor Author

Lucasczm commented Dec 7, 2022

@SuGlider updated!

@SuGlider SuGlider merged commit 04693c6 into espressif:master Dec 7, 2022
@tueddy
Copy link
Contributor

tueddy commented Dec 7, 2022

Can't test it just at the moment, but can I distinguish whether in the listing is a file or directory with this commit?
Made a comment above..

Thank's for your work!

@BlueAndi
Copy link
Contributor

BlueAndi commented Dec 29, 2022

@tueddy The seekDir() implementation will only be useful if the other functions are available in FS and VFS too, see
https://github.com/espressif/esp-idf/blob/16a4ee7c36a848ca155791677ce011f3ca75c519/components/newlib/platform_include/sys/dirent.h#L51-L57

@Lucasczm How do you use seekDir() without the other functions?

@tueddy
Copy link
Contributor

tueddy commented Dec 30, 2022

getNextFileName() works fine in 2.0.6, but how can i detect now if return value is a file or directory?

Comment on lines +497 to +499
if (file->d_type != DT_REG && file->d_type != DT_DIR) {
return "";
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This behaviour is inconsistent with openNextFile() which skips to the next file.

It's not possible to tell the difference between "end of file list" and "something that is not a file or directory".

Comment on lines +500 to +505
String fname = String(file->d_name);
String name = String(_path);
if (!fname.startsWith("/") && !name.endsWith("/")) {
name += "/";
}
name += fname;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the "path", not the "name" of the file.

This results in more effort by users of this function to remove the directory name (which they already have) from every filename.

(The openNextFile() function returns a File so it's possible to use name() or path())

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: Libraries Issue is related to Library support. Resolution: Awaiting response Waiting for response of author Type: Feature request Feature request for Arduino ESP32
Projects
Development

Successfully merging this pull request may close these issues.