diff --git a/README.md b/README.md index 5ac25bd..4680df5 100644 --- a/README.md +++ b/README.md @@ -77,12 +77,13 @@ Style::setBorderDiagonalDown(style, color) ``` ### Cell autosizing -#### ... is cool, but comes with serious performance impacts! -| Impacts of autosizing | 100k rows * 10 cols * 5 chars | 100k rows * 10 cols * 10 chars | 100k rows * 10 cols * 20 chars | 100k rows * 10 cols * 40 chars | -| ------------------------ | ----------------------------- | ------------------------------ | ------------------------------ | ------------------------------ | -| Autosizing DISABLED | 22 seconds | 22 seconds | 23 seconds | 24 seconds | -| Autosizing ENABLED | 30 seconds | 34 seconds | 40 seconds | 53 seconds | -| Performance loss in % | + 36 % | + 54 % | + 73 % | + 112 % | +#### ... is cool, but it comes with serious performance impacts, especially when dealing with multibyte characters (like ä, ß, Æ, ポ). +| Impacts of autosizing | 100k rows * 10 cols * 5 chars | 100k rows * 10 cols * 10 chars | 100k rows * 10 cols * 20 chars | 100k rows * 10 cols * 40 chars | +| ------------------------------------- | ----------------------------- | ------------------------------ | ------------------------------ | ------------------------------ | +| Autosizing OFF (Single Byte Chars) | 24 seconds | 24 seconds | 24 seconds | 26 seconds | +| Autosizing ON (Single Byte Chars) | 30 seconds (+ 25 %) | 32 seconds (+ 33 %) | 35 seconds (+ 45 %) | 43 seconds (+ 65 %) | +| Autosizing OFF (Multi Byte Chars) | 27 seconds | 28 seconds | 30 seconds | 31 seconds | +| Autosizing ON (Multi Byte Chars) | 36 seconds (+ 33 %) | 41 seconds (+ 46 %) | 49 seconds (+ 63 %) | 64 seconds (+ 106 %) | ### Additional examples ```php diff --git a/src/OneSheet/Width/WidthCalculator.php b/src/OneSheet/Width/WidthCalculator.php index 66624d5..4a505f1 100644 --- a/src/OneSheet/Width/WidthCalculator.php +++ b/src/OneSheet/Width/WidthCalculator.php @@ -42,7 +42,8 @@ public function __construct(WidthCollection $widthCollection) public function getCellWidth($value, Font $font) { $width = 0.07 * $font->getSize(); - foreach (preg_split('~~u', $value, -1, PREG_SPLIT_NO_EMPTY) as $character) { + + foreach ($this->getSingleCharacterArray($value) as $character) { if (isset($this->characterWidths[$character])) { $width += $this->characterWidths[$character]; } elseif (strlen($character)) { @@ -62,4 +63,18 @@ public function setFont(Font $font) { $this->characterWidths = $this->widthCollection->get($font->getName(), $font->getSize()); } + + /** + * Split value into individual characters. + * + * @param mixed $value + * @return array + */ + private function getSingleCharacterArray($value) + { + if (mb_strlen($value) == strlen($value)) { + return str_split($value); + } + return preg_split('~~u', $value, -1, PREG_SPLIT_NO_EMPTY); + } }