- 
                Notifications
    You must be signed in to change notification settings 
- Fork 3.6k
Description
This is:
- [ ] a bug report
- [x] a feature request
- [ ] **not** a usage question (ask them on https://stackoverflow.com/questions/tagged/phpspreadsheet or https://gitter.im/PHPOffice/PhpSpreadsheet)
What is the expected behavior?
The cell cache does not require a prefix.
What is the current behavior?
All coordinates are prefixed automatically by PhpOffice\PhpSpreadsheet\Collection\Cells
What are the steps to reproduce?
Please provide a Minimal, Complete, and Verifiable example of code that exhibits the issue without relying on an external Excel file or a web server:
<?php
require __DIR__ . '/vendor/autoload.php';
class Memory extends \PhpOffice\PhpSpreadsheet\Collection\Memory
{
    public function set($key, $value, $ttl = null)
    {
        fwrite(STDOUT, "Cache key: {$key}\n"); // prints something like "Cache key: phpspreadsheet.5c19219c3c4962.46848305.A1"
        return parent::set($key, $value, $ttl);
    }
}
\PhpOffice\PhpSpreadsheet\Settings::setCache(new Memory());
$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
$spreadsheet->getActiveSheet()->setCellValue('A1', 'foo')->setCellValue('A2', 'bar');Which versions of PhpSpreadsheet and PHP are affected?
Any version >= 1.0.0-beta
Description
The class PhpOffice\PhpSpreadsheet\Collection\Cells automatically adds a cache prefix to every key before adding it to the cache.  The prefix looks like phpspreadsheet.5c19219c3c4962.46848305..
The problem with prefixing is it ends up requiring a lot more memory if the cache adapter stores the keys in memory.  The immediately obvious issue is that we have to store the extra 39 characters for the prefix, repeated by the number of cells in the spreadsheet.  However the memory usage is even worse because Cells already stores an index of every coordinate.  If the cache keys were not prefixed PHP could reference the same value for both Cells::index and the Cache implementation's index.  Since the prefix is added PHP stores each coordinate twice, once without the prefix and once with the prefix.
I think this could be avoided by letting the cache determine if it wants to add a prefix or not. Then the cache adapter could either namespace the keys itself or the user could use a decorator like this one. It seems like the intention of the prefix is to avoid collisions and the cache should know best if it needs to worry about that.
When using the in memory cache you could avoid collisions by creating a new instance of the memory cache per worksheet. This would require changing Settings::getCache to not force a singleton since it currently returns a single cache instance for all worksheets. We would probably need to let the user specify a factory instead?
I tried working around this by making the cache adapter index the cache keys in a multidimensional array as [prefix][coordinate].  It helped memory usage but hurt performance because of all of the string operations necessary.
I benchmarked performance without prefixing and saw a 21% improvement in runtime and 22% improvement in memory usage. However there is only a 8.63% improvement in runtime and 14% improvement in memory usage if the changes in #822 are made first.