Skip to content

[browser][non-icu] HybridGlobalization checking for prefix/suffix - #85093

Merged
ilonatommy merged 11 commits into
dotnet:mainfrom
ilonatommy:hg-prefix-suffix
Apr 22, 2023
Merged

[browser][non-icu] HybridGlobalization checking for prefix/suffix#85093
ilonatommy merged 11 commits into
dotnet:mainfrom
ilonatommy:hg-prefix-suffix

Conversation

@ilonatommy

@ilonatommyilonatommy commented Apr 20, 2023

Copy link
Copy Markdown
Member

Implements a chunk of web-api based globalization. Is a part of HybridGlobalization feature and contributes to #79989.

Old, icu-based private API: GlobalizationNative_StartsWith, GlobalizationNative_EndsWith

New, non-icu private API: Interop.JsGlobalization.StartsWith, Interop.JsGlobalization.EndsWith

Affected public API (see: tests in CompareInfoTests.IsPrefix.cs, CompareInfoTests.IsSuffix):

  • CompareInfo.IsPrefix
  • CompareInfo.IsSuffix
  • String.StartsWith
  • String.EndsWith

It is faster than existing ICU version (that does not support vectorization) but the supported scope is reduced.

Test nametime ICU4C [ms]time HG [ms]increase by [times]
String, CompareInfo IsPrefix5.30021.07290.20
String, CompareInfo IsSuffix10.79071.07650.09
String, String StartsWith5.43541.15880.21
String, String EndsWith12.34111.12170.09

All changes in behavior are listed in docs\design\features\hybrid-globalization.md.

cc @SamMonoRT
cc @lewing: weightless chars removal is done by a regex after decoding the string

@ghost

Copy link
Copy Markdown

Tagging subscribers to this area: @dotnet/area-system-globalization
See info in area-owners.md if you want to be subscribed.

Issue Details

Implements a chunk of web-api based globalization. Is a part of HybridGlobalization feature and contributes to #79989.

Old, icu-based private API: GlobalizationNative_StartsWith, GlobalizationNative_EndsWith

New, non-icu private API: Interop.JsGlobalization.StartsWith, Interop.JsGlobalization.EndsWith

Affected public API (see: tests in CompareInfoTests.IsPrefix.cs, CompareInfoTests.IsSuffix):

  • CompareInfo.IsPrefix
  • CompareInfo.IsSuffix
  • String.StartsWith
  • String.EndsWith

ToDo: paste perf test results here

All changes in behavior are listed in docs\design\features\hybrid-globalization.md.

cc @SamMonoRT
cc @lewing: weightless chars removal is done by a regex after decoding the string

Author:ilonatommy
Assignees:ilonatommy
Labels:

area-System.Globalization

Milestone:-

@pavelsavarapavelsavara left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Comment threadsrc/mono/wasm/runtime/net6-legacy/hybrid-globalization.ts Outdated
@ilonatommy

ilonatommy commented Apr 20, 2023

Copy link
Copy Markdown
MemberAuthor

@pavelsavara
V8 does not have TextEncoder. Chrome has it, but it works different than

for (let i = 0; i < <any>end - <any>start; i += 2) {
const char = Module.getValue(<any>start + i, "i16");
str += String.fromCharCode(char);
}

and wrong (see failures: https://helixre107v0xdcypoyl9e7f.blob.core.windows.net/dotnet-runtime-refs-pull-85093-merge-f3fb5a2097a34532ba/WasmTestOnBrowser-Hybrid.WASM.Tests/1/console.f54019e3.log?helixlogtype=result). From this reason, I am reverting the changes to decoding algorithm. I will use the above loop for every host type.

Edit: to check out more testcases that start failing when we use the Encoder see my attempt to use it in comparison in the PR: #85098

@tarekghtarekgh added the arch-wasm WebAssembly architecture label Apr 20, 2023
@ghost

Copy link
Copy Markdown

Tagging subscribers to 'arch-wasm': @lewing
See info in area-owners.md if you want to be subscribed.

Issue Details

Implements a chunk of web-api based globalization. Is a part of HybridGlobalization feature and contributes to #79989.

Old, icu-based private API: GlobalizationNative_StartsWith, GlobalizationNative_EndsWith

New, non-icu private API: Interop.JsGlobalization.StartsWith, Interop.JsGlobalization.EndsWith

Affected public API (see: tests in CompareInfoTests.IsPrefix.cs, CompareInfoTests.IsSuffix):

  • CompareInfo.IsPrefix
  • CompareInfo.IsSuffix
  • String.StartsWith
  • String.EndsWith

It is faster than existing ICU version (that does not support vectorization) but the supported scope is reduced.

| Test name | time ICU4C [ms] | time HG [ms] | increase by [times] |
|-:|-:|-:|-:|
| String, CompareInfo IsPrefix | 5.3002 | 4.1998 | 0.79 |
| String, CompareInfo IsSuffix | 10.7907 | 4.1528 | 0.38 |
| String, String StartsWith | 5.4354 | 4.2034 | 0.77 |
| String, String EndsWith | 12.3411 | 4.0324 | 0.32 |

The above are results on the version with TextEncoder. Current version results:

Test nametime ICU4C [ms]time HG [ms]increase by [times]
String, CompareInfo IsPrefix3.10982.86830.92
String, CompareInfo IsSuffix3.03382.80770.92
String, String StartsWith3.30572.86430.86
String, String EndsWith3.68482.79590.75

All changes in behavior are listed in docs\design\features\hybrid-globalization.md.

cc @SamMonoRT
cc @lewing: weightless chars removal is done by a regex after decoding the string

Author:ilonatommy
Assignees:ilonatommy
Labels:

arch-wasm, area-System.Globalization

Milestone:-

@pavelsavara

Copy link
Copy Markdown
Member

TextEncoder ... wrong

Still LGTM, but I would love this to get explained.

  • What makes it wrong and why ?
  • Is is wrong also in other use-cases, such as JS interop ?

@ilonatommy

Copy link
Copy Markdown
MemberAuthor
  • What makes it wrong and why ?
  • Is is wrong also in other use-cases, such as JS interop ?

I am in the process of #85098 investigation (there the only change is the decoding so it's easier). When I have conculsions, I'll post there and ping you.

@ilonatommy

ilonatommy commented Apr 21, 2023

Copy link
Copy Markdown
MemberAuthor

I am in the process of #85098 investigation (there the only change is the decoding so it's easier). When I have conculsions, I'll post there and ping you.

The other PR had a logical error that was not connected with the way TextDecoder works. What is going on here:

  • we pass two strings: "%uD800 %uDC00" and "%uD800"
  • they arrive in JS correctly: as [55 296, 56 320] and [55 296]
  • decoder is able to decode the string with 2 codes but for 1 code it overflows:

image

65533 -> %uFFFD: Replacement character - used to replace an incoming character whose value is unknown or unrepresentable in Unicode.
Any code >= 55296 behaves this way, even though we can still fit them in 16 bits.
image

@ilonatommy

Copy link
Copy Markdown
MemberAuthor

TextEnxcoder is fine, its behavior just does not match NLS's behavior. V8 behaves like Windows's NLS.

@ilonatommy
ilonatommy merged commit fa5d12e into dotnet:mainApr 22, 2023
@ghostghost locked as resolved and limited conversation to collaborators May 22, 2023
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-System.Globalization

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@ilonatommy@pavelsavara@tarekgh