Skip to content

SPIFFS I/O writes (from example) get exponentially slower with size? #1360

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

Closed
schweini opened this issue Apr 26, 2018 · 11 comments
Closed

SPIFFS I/O writes (from example) get exponentially slower with size? #1360

schweini opened this issue Apr 26, 2018 · 11 comments
Labels
Status: Stale Issue is stale stage (outdated/stuck)

Comments

@schweini
Copy link

I just ran the example SPIFFS_Test. It hung the first time. I uploaded it again, and the test finished successfully.

But the write performance seems extremely slow:

Testing file I/O with /test.txt

  • writing................................................................
  • 1048576 bytes written in 45808 ms
  • reading..................................
  • 557568 bytes read in 274 ms
    Deleting file: /test.txt
  • file deleted
    Test complete

So, 45.8 seconds for 1MB of data.
Is this normal?

When I change the example to do only 1024 iterations of the write, I get:

Testing file I/O with /test.txt

  • writing................................
  • 524288 bytes written in 4862 ms

And when I put it down to 512 iterations:

Testing file I/O with /test.txt

  • writing................
  • 262144 bytes written in 1546 ms

So it seems to get very exponentially slower, the more data it has to write.

@stickbreaker
Copy link
Contributor

SPIFFs is not a file system. It is a pile of data. There is not central index, allocation table, directory. Each page block (4k) is divided into 256 byte pages, each block has one 256 byte page allocated for status and control. When a page is changed, the change is written to a new page, the old page is marked as deleted. When all 15 of the usable pages are marked delete then the whole block can be erased. But, BUT, the erase is not DONE until all 'fresh' pages have been used. This is to 'wear level' the Flash. So, to find a file, the whole pile, each deleted block has to be searched one block at a time. The file has to be found by looking at every block until it is found or the entire pile is read.
When Flash is being accessed, the CPUs are stalled because SPIFFS uses the Same FLASH chip as code is stored in. The Flash chip can only do one thing at a time.

Chuck

@schweini
Copy link
Author

schweini commented Apr 27, 2018 via email

@schweini
Copy link
Author

schweini commented Apr 27, 2018 via email

@stickbreaker
Copy link
Contributor

Lets say the file is 0 bytes long, and you append 512 bytes, it took t ms to find the file, '2p' ms to write 512.
Now the file is 512 bytes long and you append 512 bytes, it again takes t ms to find the file, plus it has to find the page that holds the 'last' page, add the new data to the last page if possible, mark the 'last' page as nolonger the last page, find a new page to store the rest of the write.
Now the file is 1024 bytes long and you append 512 bytes, again it takes tms to fine, plus scan for end of file, append data ...

Now what happens when you delete a file, Each of the individual pages has to be marked as deleted. They are not erased until needed. so if 1/2 of the SPIFFS partition is currently deleted then to find a fresh page, 1/2 of the partition has to be scanned each time a new page is needed. What about if your file ended up being stored in the last block of the partition?

Here is an optimization discussion on a SPIFFs implementation for Cortex CPUs

SPIFFs implementation for Cortex CPU

Chuck.

@everslick
Copy link
Contributor

everslick commented Apr 27, 2018

unfortunately open() is slow as well and what makes matters worse is, that flush() does not work. #1293

@CelliesProjects
Copy link
Contributor

Does SD card access on the esp32 perform better than SPIFFS in this respect?
I decided for SPIFFS over SD in a project of mine because my thought was that esp32 can always have a SPIFFS system and a SD required extra hardware.

@everslick
Copy link
Contributor

SD card works somehow better in regard with performance, but the flush() is missing in SDFS. which I mixed up with SPIFFS in the comment above. so with an SD card you have to work around the missing flush() with closing and reopening the file to really write it to the medium.

@euquiq
Copy link

euquiq commented Jul 5, 2018

SPIFFS over the ESP32 flash is excruciatingly slow. I just placed a new issue about it:

#1597

I am creating a file with 28 bytes (a text) inside in about 130-150 milliseconds.
BUT when I try to read it, it takes about 8x more time !!!

More than 1 second for reading 28 bytes. Slower than 90's Harddisks :)

@me-no-dev
Copy link
Member

so I just added a "fix" that disables timeout in the Stream portion of the File API. That means that any operation from the Stream class that was using timeoutRead or timeoutPeek is no longer waiting for the default 1 second if the end of the file has been reached.

@stale
Copy link

stale bot commented Aug 1, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the Status: Stale Issue is stale stage (outdated/stuck) label Aug 1, 2019
@stale
Copy link

stale bot commented Aug 15, 2019

This stale issue has been automatically closed. Thank you for your contributions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Stale Issue is stale stage (outdated/stuck)
Projects
None yet
Development

No branches or pull requests

6 participants