Subject: bug#47712: 27.1; Provide `string-display-width` function, which takes properties into account, `substring-width`

From: Daniel Mendler <[email-masked]>
Date: Mon, 12 Apr 2021 16:36:05 +0200

On 4/12/21 4:15 PM, Eli Zaretskii wrote:
> If these properties are ignored, they will also be ignored on display.

No, something is wrong. 'display should not be ignored.

>> But for we can still look at the micro benchmark.  The `string-width`
>> function is 200 times faster than the `string-pixel-width` function.
> 
> And if you reuse the same temp buffer?

Sorry, I should have said that I tried reusing the same buffer. But it 
was not faster when I tried that. The buffer switching has a significant 
overhead. In order to get a fair benchmark one should measure the following:

;; 1.4s
(with-temp-buffer
   (bench
    (dotimes (_ 10000)
      (erase-buffer)
      (insert test-string)
      (car (window-text-pixel-size nil (point-min) (point-max))))))

Given that benchmark the `window-text-pixel-size` function is still over 
50 times slower.

> With 0.5 millisecond per call, I don't see a problem.  And I expect
> that to go down if the buffer is reused.

No, 0.5ms per call is not acceptable. When processing 2000 strings takes 
a second, it is not viable to use this to preprocess and format many 
strings. It may be okay for computing a handful strings which are being 
displayed right away.

Given the benchmark I think it makes sense to continue to use 
`string-width` for certain use cases which can live with the limitations 
of only working correctly in text mode.

But I understand that you don't want to add a half-broken 
`string-display-width` API on top of the already half-broken 
`string-width` API. One may still discuss the implementation of a 
`substring-width` API which generalizes `string-width`.

(defun string-width (s)
   (substring-width s 0 (length s)))

(defun substring-width (s a b)
   (string-width (substring s a b)))