Opened 7 years ago
Last modified 6 years ago
#138 new defect
Unicode32String is really really slow when scrolling the text
Reported by: | Owned by: | ||
---|---|---|---|
Priority: | major | Milestone: | |
Component: | default | Keywords: | |
Cc: | Also affects CVS HEAD (eXept version): | no |
Description
I have observed that the Unicode32String is really really slow compared to the String or Unicode16String. Of course, Unicode32String can be somewhat slower as it contains more but current situation is, in my opinion, way too much.
Second thing more serious but for which I don't have any proof yet. When the Unicode32String is running for long time (rendering the text) during which it uses 1 core of the multi-core CPU (due to the VM nature of StX) to the 100%, it corrupts memory - I left it running for more than 10 minutes and after like 8 minutes my opened browser (I had only one tab opened) started to behave really weird - the normal keys started to opened different tabs, configuration; to me this behavior is similar to memory corruption. You can try to leave the below code running for long time and you will see if this can be reproduced.
The following code has String, Unicode16String, Unicode32String (uncomment the String comment block you want to run):
maxCharBuffer := 10000. charToDisplay := 100000. "/String "contents := String new: charToDisplay. tempContents := String new." "/Unicode16String "contents := Unicode16String new: charToDisplay. tempContents := Unicode16String new." "/Unicode32String contents := Unicode32String new: charToDisplay. tempContents := Unicode32String new. aLetterCollection := OrderedCollection new. startingLetter := $A. iterrations := (charToDisplay / maxCharBuffer). iterrations isInteger ifFalse:[ iterrations := (iterrations asFloat) floor + 1. ]. (1 to: iterrations) do: [:aNumber | aLetterCollection add: (((startingLetter asInteger - 1) + aNumber) asCharacter). ]. aLetterCollection do: [:aLetter| charToDisplay > maxCharBuffer ifTrue: [ pickContents := contents copyFrom:1 to:maxCharBuffer. pickContents replaceAll: Character space with: aLetter. tempContents := tempContents, pickContents. contents := contents copyFrom:(maxCharBuffer+1) to:charToDisplay. charToDisplay := charToDisplay - maxCharBuffer. "/pickContents inspect. "/tempContents inspect. ] ifFalse: [ remainingContents := contents copyFrom:1 to:charToDisplay. remainingContents replaceAll: Character space with: aLetter. contents := tempContents, remainingContents. ]. ]. top := StandardSystemView new. top extent:300@200. textView := EditTextView new. textView origin:0.0 @ 0.0 corner:1.0 @ 1.0. top addSubView:textView. textView contents: contents. top open.
Attachments (2)
Change History (5)
by , 7 years ago
Attachment: | Unicode32String_slow.mp4 added |
---|
comment:1 by , 7 years ago
Summary: | Unicode32String is really really slow → Unicode32String is really really slow when scrolling the text |
---|
by , 7 years ago
Attachment: | WinWorkstation-widthOf:from:to:inFont:.st added |
---|
comment:2 by , 7 years ago
One problem is that edit text view needs to compute a width of a sub-string in order to determine pixel-position of a cursor. The string is in this case Unicode32String
and as such cannot be passed to Window's GetTextExtentPoint32W()
as it takes only UTF16 strings.
So, in order to compute the width, original string have to be converted to UTF16 string. Current code converts whole original string, which takes very long. By more careful coding
(see attached change) one can reduce the conversion to what is actually needed.
Still, in provided testcase this conversion takes a lot of a time so we may need to optimize more:
- We may optimize
Unicode16String >> copyFrom:to:with:startingAt:
and special-case it for copying fromUnicode32String
- and possibly manually unroll the loop (but remember, we have to bail-out iff the character in source does not fit into 16bit range)
- We may do the conversion directly in
WinWorkstation>>widthOf:from:to:inFont:in:with:
into some static and/or quick-allocated buffer and then useGetTextExtentPoint32W()
.
Further optimization may be done at higher-level in EditTextView
itself, though this would be the thougest and I'd resort to that after implementing all of the above.
comment:3 by , 6 years ago
Apparently the textView is slow even when using just Unicode16String
.
You can test it on the following example:
testString := Unicode16String new. testString := 'コーヒーアイスクリームケーキビールすしかき'. top := StandardSystemView new. top extent:300@200. textView := EditTextView new. textView origin:0.0 @ 0.0 corner:1.0 @ 1.0. top addSubView:textView. 1 to: 1000 do: [ :each | textView paste:testString ]. top open.
Showing comparison of String, Unicode16String, Unicode32String