Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[json] Use S.R.I vectors in JsonReaderHelper #81758

Merged

Conversation

radekdoulik
Copy link
Member

wasm performance improvement

measurement new simd old simd nosimd
Json, non-ASCII text deserialize 0.4234ms 0.4280ms 0.4234ms
Json, small deserialize 0.0376ms 0.0402ms 0.0397ms
Json, large deserialize 10.4231ms 11.1614ms 11.0021ms

wasm performance improvement

| measurement | new simd | old simd | nosimd |
|-:|-:|-:|-:|
|       Json, non-ASCII text deserialize |     0.4234ms |     0.4280ms |     0.4234ms |
|                Json, small deserialize |     0.0376ms |     0.0402ms |     0.0397ms |
|                Json, large deserialize |    10.4231ms |    11.1614ms |    11.0021ms |
@ghost
Copy link

ghost commented Feb 7, 2023

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

Issue Details

wasm performance improvement

measurement new simd old simd nosimd
Json, non-ASCII text deserialize 0.4234ms 0.4280ms 0.4234ms
Json, small deserialize 0.0376ms 0.0402ms 0.0397ms
Json, large deserialize 10.4231ms 11.1614ms 11.0021ms
Author: radekdoulik
Assignees: radekdoulik
Labels:

area-System.Text.Json

Milestone: -

@radekdoulik
Copy link
Member Author

Now to measure the CLR perf.

@radekdoulik
Copy link
Member Author

radekdoulik commented Feb 7, 2023

> dotnet run --artifacts="artifacts/before" -c Release -f net8.0 --filter *Text.Json*Read* --coreRun d:\git\wa-local\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\CoreRun.exe
> dotnet run --artifacts="artifacts/after" -c Release -f net8.0 --filter *Text.Json*Read* --coreRun d:\git\wa-local\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\CoreRun.exe
> dotnet run --base ..\..\benchmarks\micro\artifacts\before --diff ..\..\benchmarks\micro\artifacts\after --threshold 2%
summary:
better: 170, geomean: 1.120
worse: 15, geomean: 1.080
total diff: 185
Slower diff/base Base Median (ns) Diff Median (ns) Modality
System.Text.Json.Tests.Perf_Reader.ReadMultiSpanSequenceEmptyLoop(IsDataCompact: 1.32 174.67 230.27
System.Text.Json.Tests.Perf_Reader.ReadReturnBytes(IsDataCompact: False, TestCas 1.18 91.47 107.96
System.Text.Json.Tests.Perf_Reader.ReadSpanEmptyLoop(IsDataCompact: True, TestCa 1.13 1964.42 2211.09
System.Text.Json.Serialization.Tests.ReadJson<ImmutableSortedDictionary<String, 1.09 64071.49 69845.51
System.Text.Json.Serialization.Tests.ReadJson.Deseria 1.09 1618.14 1760.57
System.Text.Json.Serialization.Tests.ReadJson.Deseri 1.09 302.07 327.76
System.Text.Json.Serialization.Tests.ReadJson.Deseri 1.06 356.91 377.47
System.Text.Json.Serialization.Tests.ReadJson<ImmutableSortedDictionary<String, 1.05 65186.69 68711.29
System.Text.Json.Tests.Perf_Depth.ReadSpanEmptyLoop(Depth: 65) 1.04 2604.85 2705.15
System.Text.Json.Tests.Perf_Reader.ReadReturnBytes(IsDataCompact: True, TestCase 1.04 3612.22 3745.75
System.Text.Json.Serialization.Tests.ReadJson.Deseria 1.04 1096.43 1136.79
System.Text.Json.Tests.Perf_Reader.ReadMultiSpanSequenceEmptyLoop(IsDataCompact: 1.04 155.63 161.24
System.Text.Json.Serialization.Tests.ReadJson.Deseri 1.03 348.85 360.75
System.Text.Json.Serialization.Tests.ReadJson<ImmutableSortedDictionary<String, 1.03 67303.70 69273.53
System.Text.Json.Serialization.Tests.ReadJson.Deseria 1.02 1119.73 1146.20
Faster base/diff Base Median (ns) Diff Median (ns) Modality
System.Text.Json.Reader.Tests.Perf_Base64.ReadBase64EncodedByteArray_NoEscaping( 1.42 106.42 74.98
System.Text.Json.Tests.Perf_Reader.ReadSpanEmptyLoop(IsDataCompact: True, TestCa 1.35 54171.11 40269.90
System.Text.Json.Tests.Perf_Reader.ReadSingleSpanSequenceEmptyLoop(IsDataCompact 1.34 81990.53 61079.60
System.Text.Json.Tests.Perf_Segment.ReadSingleSegmentSequenceByN(numberOfBytes: 1.33 838665.13 629626.25
System.Text.Json.Tests.Perf_Segment.ReadSingleSegmentSequenceByN(numberOfBytes: 1.33 801958.13 602781.25
System.Text.Json.Tests.Perf_Segment.ReadMultiSegmentSequence(segmentSize: 8192, 1.31 843846.71 645042.00
System.Text.Json.Tests.Perf_Reader.ReadMultiSpanSequenceEmptyLoop(IsDataCompact: 1.30 2130.97 1633.98
System.Text.Json.Tests.Perf_Segment.ReadSingleSegmentSequence(TestCase: Json400K 1.30 789941.88 606954.81
System.Text.Json.Tests.Perf_Reader.ReadReturnBytes(IsDataCompact: False, TestCas 1.30 93536.98 72216.62
System.Text.Json.Tests.Perf_Segment.ReadSingleSegmentSequenceByN(numberOfBytes: 1.29 79237.91 61536.18
System.Text.Json.Tests.Perf_Segment.ReadMultiSegmentSequence(segmentSize: 8192, 1.28 85788.83 66994.20
System.Text.Json.Tests.Perf_Reader.ReadSingleSpanSequenceEmptyLoop(IsDataCompact 1.28 53131.10 41496.18
System.Text.Json.Tests.Perf_Segment.ReadSingleSegmentSequence(TestCase: Json40KB 1.28 78482.95 61379.17
System.Text.Json.Tests.Perf_Segment.ReadMultiSegmentSequenceUsingSpan(segmentSiz 1.28 825731.58 646651.56
System.Text.Json.Tests.Perf_Segment.ReadMultiSegmentSequence(segmentSize: 4096, 1.27 841121.38 662677.86
System.Text.Json.Tests.Perf_Segment.ReadMultiSegmentSequence(segmentSize: 4096, 1.26 86886.03 68862.44
System.Text.Json.Tests.Perf_Reader.ReadSpanEmptyLoop(IsDataCompact: False, TestC 1.26 78381.39 62192.98
System.Text.Json.Tests.Perf_Reader.ReadMultiSpanSequenceEmptyLoop(IsDataCompact: 1.25 54474.93 43674.11
System.Text.Json.Tests.Perf_Segment.ReadSingleSegmentSequenceByN(numberOfBytes: 1.25 77304.46 62027.01
System.Text.Json.Tests.Perf_Reader.ReadSingleSpanSequenceEmptyLoop(IsDataCompact 1.25 2003.03 1607.78
System.Text.Json.Tests.Perf_Segment.ReadMultiSegmentSequenceUsingSpan(segmentSiz 1.24 76811.70 61760.95
System.Text.Json.Tests.Perf_Reader.ReadReturnBytes(IsDataCompact: True, TestCase 1.24 64054.52 51556.49
System.Text.Json.Tests.Perf_Reader.ReadSpanEmptyLoop(IsDataCompact: False, TestC 1.22 3309.63 2707.95
System.Text.Json.Tests.Perf_Reader.ReadSingleSpanSequenceEmptyLoop(IsDataCompact 1.22 100.17 82.27
System.Text.Json.Tests.Perf_Reader.ReadSingleSpanSequenceEmptyLoop(IsDataCompact 1.21 1257.69 1037.76
System.Text.Json.Tests.Perf_Reader.ReadMultiSpanSequenceEmptyLoop(IsDataCompact: 1.20 79941.10 66622.79
System.Text.Json.Tests.Perf_Segment.ReadMultiSegmentSequenceUsingSpan(segmentSiz 1.20 7608.40 6349.20
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromStr 1.20 28761.76 24011.45
System.Text.Json.Tests.Perf_Reader.ReadSingleSpanSequenceEmptyLoop(IsDataCompact 1.19 8920.87 7471.39 several?
System.Text.Json.Tests.Perf_Segment.ReadMultiSegmentSequenceUsingSpan(segmentSiz 1.19 839708.88 704922.83
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromRea 1.19 35938.47 30224.77
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromUtf8Byte 1.19 21762.25 18352.61
System.Text.Json.Serialization.Tests.ReadJson.Deseriali 1.18 418062.50 352830.00
System.Text.Json.Serialization.Tests.ReadJson<Dictionary<String, String>>.Deseri 1.18 21659.53 18336.88
System.Text.Json.Tests.Perf_Reader.ReadSpanEmptyLoop(IsDataCompact: False, TestC 1.18 1928.63 1634.17
System.Text.Json.Tests.Perf_Reader.ReadSingleSpanSequenceEmptyLoop(IsDataCompact 1.18 7796.48 6612.16
System.Text.Json.Serialization.Tests.ReadJson.Deseriali 1.17 426903.17 363564.82
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromRea 1.17 36337.92 30999.38
System.Text.Json.Serialization.Tests.ReadJson.Deseriali 1.17 312598.63 267386.44
System.Text.Json.Tests.Perf_Segment.ReadMultiSegmentSequenceUsingSpan(segmentSiz 1.17 82573.17 70753.89
System.Text.Json.Tests.Perf_Segment.ReadSingleSegmentSequenceByN(numberOfBytes: 1.17 7236.55 6210.89
System.Text.Json.Serialization.Tests.ReadJson.Deseriali 1.16 303100.66 262059.70
System.Text.Json.Serialization.Tests.ReadJson.Deseriali 1.16 315906.71 273245.65
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromStream(M 1.15 22244.77 19279.93
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromUtf 1.15 25776.66 22347.23
System.Text.Json.Serialization.Tests.ReadJson.Deseriali 1.15 304603.62 264193.54
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromUtf 1.15 26104.20 22644.35
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromStr 1.15 26893.72 23334.47
System.Text.Json.Tests.Perf_Reader.ReadSpanEmptyLoop(IsDataCompact: False, TestC 1.15 11422.54 9913.06
System.Text.Json.Tests.Perf_Reader.ReadReturnBytes(IsDataCompact: True, TestCase 1.15 96.44 83.71
System.Text.Json.Tests.Perf_Reader.ReadMultiSpanSequenceEmptyLoop(IsDataCompact: 1.15 1026.31 894.37
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromStr 1.15 26812.74 23399.71
System.Text.Json.Tests.Perf_Segment.ReadSingleSegmentSequenceByN(numberOfBytes: 1.14 7155.73 6257.28
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromStr 1.14 28460.07 24904.35
System.Text.Json.Tests.Perf_Reader.ReadMultiSpanSequenceEmptyLoop(IsDataCompact: 1.14 3467.05 3042.88
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromReader(M 1.14 24705.74 21684.42
System.Text.Json.Serialization.Tests.ReadJson.Deseriali 1.14 348169.97 306564.01
System.Text.Json.Tests.Perf_Reader.ReadSpanEmptyLoop(IsDataCompact: True, TestCa 1.13 622.57 549.56
System.Text.Json.Serialization.Tests.ReadJson<Dictionary<String, String>>.Deseri 1.13 21393.31 18923.10
System.Text.Json.Tests.Perf_Reader.ReadSpanEmptyLoop(IsDataCompact: False, TestC 1.13 91.91 81.30
System.Text.Json.Tests.Perf_Reader.ReadSpanEmptyLoop(IsDataCompact: False, TestC 1.13 6876.16 6093.51
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromString(M 1.13 21209.04 18797.52
System.Text.Json.Serialization.Tests.ReadJson<Nullable>.Deserial 1.13 262.20 232.95
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromStream(M 1.12 21805.44 19415.31
System.Text.Json.Serialization.Tests.ReadJson.Deseriali 1.12 347375.62 309636.34
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromUtf8Byte 1.12 21000.20 18738.51
System.Text.Json.Serialization.Tests.ReadJson<Dictionary<String, String>>.Deseri 1.12 17321.19 15503.53
System.Text.Json.Reader.Tests.Perf_Base64.ReadBase64EncodedByteArray_HeavyEscapi 1.12 83.81 75.08
System.Text.Json.Tests.Perf_Reader.ReadMultiSpanSequenceEmptyLoop(IsDataCompact: 1.12 3282.79 2942.93
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromStream(M 1.11 33555.98 30116.36
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromString(M 1.11 21569.83 19359.33
System.Text.Json.Tests.Perf_Reader.ReadReturnBytes(IsDataCompact: False, TestCas 1.11 13050.39 11716.77
System.Text.Json.Serialization.Tests.ReadJson<HashSet>.DeserializeFromSt 1.11 11415.93 10264.64
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromReader(M 1.11 38098.55 34270.56
System.Text.Json.Tests.Perf_Reader.ReadSpanEmptyLoop(IsDataCompact: True, TestCa 1.11 7266.47 6538.15
System.Text.Json.Tests.Perf_Reader.ReadSpanEmptyLoop(IsDataCompact: True, TestCa 1.11 4522.99 4071.31
System.Text.Json.Reader.Tests.Perf_Base64.ReadBase64EncodedByteArray_NoEscaping( 1.11 258.01 232.29
System.Text.Json.Tests.Perf_Reader.ReadReturnBytes(IsDataCompact: False, TestCas 1.11 7969.61 7179.94
System.Text.Json.Tests.Perf_Reader.ReadSingleSpanSequenceEmptyLoop(IsDataCompact 1.11 4685.97 4222.20
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromReader(M 1.11 24335.70 21931.73
System.Text.Json.Serialization.Tests.ReadMissingAndCaseInsensitive.Mis 1.11 822.24 741.03
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromStream(M 1.11 33820.33 30480.44
System.Text.Json.Tests.Perf_Segment.ReadMultiSegmentSequence(segmentSize: 4096, 1.11 7279.79 6574.63
System.Text.Json.Tests.Perf_Reader.ReadSpanEmptyLoop(IsDataCompact: True, TestCa 1.11 3156.51 2855.79
System.Text.Json.Tests.Perf_Segment.ReadMultiSegmentSequence(segmentSize: 8192, 1.10 6921.42 6269.15
System.Text.Json.Tests.Perf_Reader.ReadMultiSpanSequenceEmptyLoop(IsDataCompact: 1.10 741.51 671.91
System.Text.Json.Tests.Perf_Depth.ReadSpanEmptyLoop(Depth: 64) 1.10 2546.23 2310.43
System.Text.Json.Tests.Perf_Reader.ReadSingleSpanSequenceEmptyLoop(IsDataCompact 1.10 86.22 78.28
System.Text.Json.Tests.Perf_Reader.ReadMultiSpanSequenceEmptyLoop(IsDataCompact: 1.10 7419.63 6736.33
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromReader(M 1.10 37544.22 34115.83
System.Text.Json.Reader.Tests.Perf_Base64.ReadBase64EncodedByteArray_HeavyEscapi 1.10 256.44 233.38
System.Text.Json.Tests.Perf_Reader.ReadMultiSpanSequenceEmptyLoop(IsDataCompact: 1.10 7132.67 6500.95
System.Text.Json.Tests.Perf_Reader.ReadMultiSpanSequenceEmptyLoop(IsDataCompact: 1.10 12569.76 11463.01
System.Text.Json.Tests.Perf_Depth.ReadSpanEmptyLoop(Depth: 512) 1.10 21750.94 19836.66
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromString(M 1.10 32965.73 30067.96
System.Text.Json.Tests.Perf_Reader.ReadReturnBytes(IsDataCompact: True, TestCase 1.10 5620.48 5126.45
System.Text.Json.Serialization.Tests.ReadJson<HashSet>.DeserializeFromUt 1.10 10241.48 9343.25
System.Text.Json.Tests.Perf_Reader.ReadSingleSpanSequenceEmptyLoop(IsDataCompact 1.10 905.02 826.01
System.Text.Json.Tests.Perf_Reader.ReadSpanEmptyLoop(IsDataCompact: False, TestC 1.09 886.41 809.60
System.Text.Json.Tests.Perf_Reader.ReadSpanEmptyLoop(IsDataCompact: False, TestC 1.09 9146.05 8356.03
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromString(M 1.09 33490.36 30654.80
System.Text.Json.Tests.Perf_Reader.ReadSingleSpanSequenceEmptyLoop(IsDataCompact 1.09 3086.99 2826.70
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromUtf8Byte 1.09 32250.46 29657.21
System.Text.Json.Tests.Perf_Segment.ReadMultiSegmentSequenceUsingSpan(segmentSiz 1.09 6951.29 6396.26
System.Text.Json.Serialization.Tests.ReadJson<Nullable>.Deserial 1.09 134.13 123.50
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromReader(Mo 1.08 1737.49 1602.14
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromRea 1.08 672.36 621.36
System.Text.Json.Serialization.Tests.ReadJson<Dictionary<String, String>>.Deseri 1.08 16654.39 15391.53
System.Text.Json.Serialization.Tests.ReadJson<HashSet>.DeserializeFromUt 1.08 9963.63 9220.99
System.Text.Json.Tests.Perf_Reader.ReadReturnBytes(IsDataCompact: True, TestCase 1.08 741.15 686.11
System.Text.Json.Serialization.Tests.ReadJson<Nullable>.Deserial 1.08 253.47 235.11
System.Text.Json.Tests.Perf_Reader.ReadSingleSpanSequenceEmptyLoop(IsDataCompact 1.08 609.54 565.90
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromUtf8Byte 1.08 32994.09 30646.49
System.Text.Json.Tests.Perf_Reader.ReadSingleSpanSequenceEmptyLoop(IsDataCompact 1.08 6809.89 6330.47
System.Text.Json.Serialization.Tests.ReadJson<Nullable>.Deserial 1.07 180.33 168.02
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromReader( 1.07 637.58 594.60
System.Text.Json.Serialization.Tests.ReadJson<ImmutableDictionary<String, String 1.07 39029.17 36469.40
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromString(Mo 1.07 1275.61 1195.49
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromString( 1.07 562.12 527.59
System.Text.Json.Tests.Perf_Reader.ReadSingleSpanSequenceEmptyLoop(IsDataCompact 1.07 1973.22 1852.33
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromReader(Mo 1.06 1737.86 1633.76
System.Text.Json.Tests.Perf_Reader.ReadReturnBytes(IsDataCompact: True, TestCase 1.06 8495.02 7994.88
System.Text.Json.Serialization.Tests.ReadJson<Nullable>.Deserial 1.06 180.81 170.20
System.Text.Json.Tests.Perf_Segment.ReadSingleSegmentSequence(TestCase: Json4KB) 1.06 6792.28 6405.90
System.Text.Json.Tests.Perf_Reader.ReadMultiSpanSequenceEmptyLoop(IsDataCompact: 1.06 4784.88 4515.35
System.Text.Json.Tests.Perf_Reader.ReadMultiSpanSequenceEmptyLoop(IsDataCompact: 1.06 1178.14 1112.16
System.Text.Json.Serialization.Tests.ReadJson<ImmutableDictionary<String, String 1.06 43810.83 41432.18
System.Text.Json.Serialization.Tests.ReadMissingAndCaseInsensitive.Cas 1.06 1211.93 1146.40
System.Text.Json.Serialization.Tests.ReadJson.Deseria 1.06 1307.65 1237.45
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromStr 1.06 473.54 448.54
System.Text.Json.Tests.Perf_Reader.ReadMultiSpanSequenceEmptyLoop(IsDataCompact: 1.05 2126.27 2017.09
System.Text.Json.Serialization.Tests.ReadJson<HashSet>.DeserializeFromSt 1.05 10270.79 9760.28
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromUtf 1.05 405.65 385.67
System.Text.Json.Serialization.Tests.ReadJson<HashSet>.DeserializeFromRe 1.05 12909.50 12273.67
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromReader( 1.05 649.62 617.64 several?
System.Text.Json.Serialization.Tests.ReadJson<ImmutableDictionary<String, String 1.05 44046.37 41899.03
System.Text.Json.Serialization.Tests.ReadJson<Dictionary<String, String>>.Deseri 1.05 15760.75 15009.63
System.Text.Json.Serialization.Tests.ReadMissingAndCaseInsensitive.Bas 1.05 1195.41 1138.53
System.Text.Json.Serialization.Tests.ReadJson.Deseri 1.05 528.79 504.63
System.Text.Json.Serialization.Tests.ReadJson<Dictionary<String, String>>.Deseri 1.05 16659.90 15900.11
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromString( 1.05 558.45 533.04
System.Text.Json.Tests.Perf_Reader.ReadSingleSpanSequenceEmptyLoop(IsDataCompact 1.05 3142.26 3001.03
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromUtf8Byt 1.05 433.95 414.52
System.Text.Json.Tests.Perf_Reader.ReadSingleSpanSequenceEmptyLoop(IsDataCompact 1.05 11585.10 11070.39
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromUtf 1.05 403.93 386.06
System.Text.Json.Serialization.Tests.ReadJson<ImmutableDictionary<String, String 1.05 38144.10 36464.77
System.Text.Json.Serialization.Tests.ReadJson<HashSet>.DeserializeFromSt 1.05 10108.09 9667.40
System.Text.Json.Serialization.Tests.ReadJson<ImmutableDictionary<String, String 1.04 40474.48 38764.98
System.Text.Json.Serialization.Tests.ReadJson.Deseri 1.04 541.97 519.52
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromUtf8Byt 1.04 436.26 418.22
System.Text.Json.Tests.Perf_Reader.ReadSpanEmptyLoop(IsDataCompact: True, TestCa 1.04 1095.73 1051.46
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromStream(Mo 1.04 1529.61 1468.39
System.Text.Json.Tests.Perf_Reader.ReadReturnBytes(IsDataCompact: False, TestCas 1.04 3278.89 3151.39
System.Text.Json.Serialization.Tests.ReadJson<Nullable>.Deserial 1.04 130.16 125.12
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromStream( 1.04 797.99 767.15
System.Text.Json.Tests.Perf_Depth.ReadSpanEmptyLoop(Depth: 1) 1.04 73.29 70.53
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromStr 1.04 722.48 696.43
System.Text.Json.Serialization.Tests.ReadJson<Nullable>.Deserial 1.04 339.48 327.65
System.Text.Json.Tests.Utf8JsonReaderCommentsTests.Utf8JsonReaderCommentParsing( 1.04 99.88 96.40
System.Text.Json.Serialization.Tests.ReadJson<Dictionary<String, String>>.Deseri 1.03 16971.16 16398.32
System.Text.Json.Serialization.Tests.ReadJson<ImmutableDictionary<String, String 1.03 40243.04 38957.57
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromRea 1.03 655.69 635.81
System.Text.Json.Tests.Perf_Reader.ReadSpanEmptyLoop(IsDataCompact: True, TestCa 1.03 71.99 69.85
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromStr 1.03 458.72 445.49
System.Text.Json.Tests.Utf8JsonReaderCommentsTests.Utf8JsonReaderCommentParsing( 1.03 579.78 564.64
System.Text.Json.Serialization.Tests.ReadMissingAndCaseInsensitive.Cas 1.03 1175.46 1144.98
System.Text.Json.Serialization.Tests.ReadJson<ImmutableSortedDictionary<String, 1.03 68110.28 66385.49
System.Text.Json.Serialization.Tests.ReadJson<ImmutableSortedDictionary<String, 1.02 62828.90 61311.04
System.Text.Json.Tests.Perf_Reader.ReadReturnBytes(IsDataCompact: True, TestCase 1.02 2286.91 2233.90
System.Text.Json.Tests.Perf_Reader.ReadReturnBytes(IsDataCompact: True, TestCase 1.02 1425.06 1392.77

Copy link
Member

@lewing lewing left a comment

Choose a reason for hiding this comment

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

lgtm

@xtqqczze
Copy link
Contributor

xtqqczze commented Feb 8, 2023

@stephentoub

I think new IndexOfAnyValues would be suitable instead (#78204):

private static readonly IndexOfAnyValues<byte> s_quoteOrAnyControlOrBackSlash = IndexOfAnyValues.Create(
    "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"u8 +
    "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"u8 +
    "\"\\"u8;

And then replace the callsites of IndexOfQuoteOrAnyControlOrBackSlash with:

span.IndexOfAny(s_quoteOrAnyControlOrBackSlash);

@radekdoulik radekdoulik marked this pull request as ready for review February 8, 2023 12:18
@radekdoulik radekdoulik merged commit 43a60c8 into dotnet:main Feb 8, 2023
@radekdoulik
Copy link
Member Author

@stephentoub

I think new IndexOfAnyValues would be suitable instead (#78204):

private static readonly IndexOfAnyValues<byte> s_quoteOrAnyControlOrBackSlash = IndexOfAnyValues.Create(
    "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"u8 +
    "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"u8 +
    "\"\\"u8;

And then replace the callsites of IndexOfQuoteOrAnyControlOrBackSlash with:

span.IndexOfAny(s_quoteOrAnyControlOrBackSlash);

I think the IndexOfAnyValues<byte> with all the chars is too long to be effective. Out of curiosity I measured it and it was slower in most cases.

summary:
better: 31, geomean: 1.082
worse: 116, geomean: 1.061
total diff: 147

@stephentoub
Copy link
Member

@MihaZupan
Copy link
Member

Out of curiosity I measured it and it was slower in most cases.

Were these results from WASM? If not, can you post the results for how much slower they were if you have them handy?

For this set of values, IndexOfAnyValues would give you an implementation that used this. That workhorse is fast for arbitrary ASCII sets, but more expensive than a custom implementation doing source < lessThan || source == val0 || source == val1.

IndexOfAnyValues could be extended to recognize similar patterns, we just haven't done so yet as it hasn't showed up as a common scenario.

It's also worth noting that this IndexOfAnyValues implementation is only used on X86 and ARM64 hardware. As SIMD support is brought to WASM, we should look into teaching IndexOfAnyValues about it to speed up all the places already using it.

@stephentoub
Copy link
Member

That workhorse is fast for arbitrary ASCII sets, but more expensive than a custom implementation doing source < lessThan || source == val0 || source == val1. IndexOfAnyValues could be extended to recognize similar patterns, we just haven't done so yet as it hasn't showed up as a common scenario.

If it's meaningfully faster, I'd be keen on moving the implementation into IndexOfAnyValues and then having Json just use IndexOfAnyValues. The nice thing about the IndexOfAnyValues.Create design is optimizing for this case doesn't increase the API surface area at all, and if it's a matter of shipping the custom vectorized routine in Json where it only benefits Json, or shipping the custom vectorized routine underneath IndexOfAnyValues where it then benefits both Json and anyone else who happens to have a similar pattern, I'd much rather get the larger benefit and keep the Json codebase smaller and custom-vectorization-free.

If it's not meaningfully faster, then I'd be keen on deleting the implementation from Json and having it just use the existing algorithms underlying IndexOfAnyValues.

Either way, it'd be nice to switch Json to using IndexOfAnyValues.

@radekdoulik
Copy link
Member Author

Out of curiosity I measured it and it was slower in most cases.

Were these results from WASM? If not, can you post the results for how much slower they were if you have them handy?

These were measured on win/amd/x64. I am adding the detailed ouput below.

IndexOfAnyValues could be extended to recognize similar patterns, we just haven't done so yet as it hasn't showed up as a common scenario.

That would be fine too for wasm. The main motivation here was to use Vector128, ExtractMostSignificantBits and TrailingZeroCount, which is newer and we have fast path for it. Having it use improved span's IndexOfAny would be nice, it will be less code to maintain as well.

It's also worth noting that this IndexOfAnyValues implementation is only used on X86 and ARM64 hardware. As SIMD support is brought to WASM, we should look into teaching IndexOfAnyValues about it to speed up all the places already using it.

If it uses platform specific SIMD API for arm/intel I can try to extend it to use S.R.I.Wasm.PackedSimd (which is not complete yet).

Detailed results:

summary:
better: 31, geomean: 1.082
worse: 116, geomean: 1.061
total diff: 147

Slower diff/base Base Median (ns) Diff Median (ns) Modality
System.Text.Json.Tests.Perf_Reader.ReadSingleSpanSequenceEmptyLoop(IsDataCompact 1.27 82.27 104.32
System.Text.Json.Tests.Perf_Reader.ReadSingleSpanSequenceEmptyLoop(IsDataCompact 1.15 78.28 90.34
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromReader(M 1.15 34115.83 39092.80
System.Text.Json.Tests.Perf_Reader.ReadMultiSpanSequenceEmptyLoop(IsDataCompact: 1.14 894.37 1022.04
System.Text.Json.Tests.Perf_Segment.ReadMultiSegmentSequence(segmentSize: 4096, 1.14 6574.63 7478.44
System.Text.Json.Serialization.Tests.ReadJson<Dictionary<String, String>>.Deseri 1.13 15503.53 17567.37
System.Text.Json.Tests.Perf_Depth.ReadSpanEmptyLoop(Depth: 512) 1.13 19836.66 22476.76
System.Text.Json.Tests.Perf_Reader.ReadMultiSpanSequenceEmptyLoop(IsDataCompact: 1.13 43674.11 49461.71
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromUtf8Byt 1.13 418.22 473.55
System.Text.Json.Tests.Perf_Segment.ReadMultiSegmentSequence(segmentSize: 8192, 1.12 66994.20 75311.69
System.Text.Json.Serialization.Tests.ReadJson<Dictionary<String, String>>.Deseri 1.11 18336.88 20445.23
System.Text.Json.Tests.Perf_Segment.ReadSingleSegmentSequenceByN(numberOfBytes: 1.11 602781.25 668774.22
System.Text.Json.Tests.Perf_Reader.ReadSpanEmptyLoop(IsDataCompact: False, TestC 1.11 6093.51 6734.56
System.Text.Json.Tests.Perf_Segment.ReadMultiSegmentSequenceUsingSpan(segmentSiz 1.10 6349.20 6997.96
System.Text.Json.Tests.Perf_Reader.ReadMultiSpanSequenceEmptyLoop(IsDataCompact: 1.10 2017.09 2214.85
System.Text.Json.Serialization.Tests.ReadJson<HashSet>.DeserializeFromUt 1.09 9343.25 10226.84
System.Text.Json.Serialization.Tests.ReadMissingAndCaseInsensitive.Bas 1.08 1138.53 1232.70
System.Text.Json.Tests.Perf_Segment.ReadSingleSegmentSequence(TestCase: Json40KB 1.08 61379.17 66454.74
System.Text.Json.Serialization.Tests.ReadJson<ImmutableSortedDictionary<String, 1.08 67174.55 72549.91
System.Text.Json.Serialization.Tests.ReadJson<HashSet>.DeserializeFromUt 1.08 9220.99 9956.72
System.Text.Json.Serialization.Tests.ReadJson<Dictionary<String, String>>.Deseri 1.08 15009.63 16184.98
System.Text.Json.Tests.Perf_Reader.ReadReturnBytes(IsDataCompact: False, TestCas 1.08 72216.62 77827.08
System.Text.Json.Serialization.Tests.ReadJson<HashSet>.DeserializeFromSt 1.08 10264.64 11058.57
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromReader(Mo 1.08 1602.14 1724.48
System.Text.Json.Serialization.Tests.ReadJson<HashSet>.DeserializeFromSt 1.08 9760.28 10504.25
System.Text.Json.Tests.Perf_Segment.ReadSingleSegmentSequence(TestCase: Json400K 1.08 606954.81 652837.63
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromReader( 1.08 594.60 639.34
System.Text.Json.Serialization.Tests.ReadJson<ImmutableDictionary<String, String 1.07 36469.40 39191.01
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromString( 1.07 527.59 566.31
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromStream(M 1.07 30480.44 32688.82
System.Text.Json.Reader.Tests.Perf_Base64.ReadBase64EncodedByteArray_NoEscaping( 1.07 232.29 249.06
System.Text.Json.Tests.Perf_Reader.ReadReturnBytes(IsDataCompact: True, TestCase 1.07 2233.90 2391.73
System.Text.Json.Tests.Perf_Reader.ReadSingleSpanSequenceEmptyLoop(IsDataCompact 1.07 61079.60 65359.99
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromUtf8Byte 1.07 18352.61 19627.03
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromStream(M 1.07 30116.36 32203.54
System.Text.Json.Reader.Tests.Perf_Base64.ReadBase64EncodedByteArray_HeavyEscapi 1.07 233.38 249.35
System.Text.Json.Tests.Perf_Segment.ReadMultiSegmentSequenceUsingSpan(segmentSiz 1.07 646651.56 690835.93
System.Text.Json.Tests.Perf_Segment.ReadMultiSegmentSequence(segmentSize: 8192, 1.07 6269.15 6695.28
System.Text.Json.Serialization.Tests.ReadJson<ImmutableDictionary<String, String 1.07 36464.77 38941.24
System.Text.Json.Tests.Perf_Reader.ReadSingleSpanSequenceEmptyLoop(IsDataCompact 1.07 2826.70 3017.94
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromString(M 1.07 18797.52 20047.84
System.Text.Json.Reader.Tests.Perf_Base64.ReadBase64EncodedByteArray_NoEscaping( 1.06 74.98 79.85
System.Text.Json.Serialization.Tests.ReadJson<Dictionary<String, String>>.Deseri 1.06 16398.32 17459.41
System.Text.Json.Tests.Perf_Segment.ReadMultiSegmentSequenceUsingSpan(segmentSiz 1.06 61760.95 65640.93
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromString(M 1.06 30067.96 31948.34
System.Text.Json.Tests.Perf_Reader.ReadReturnBytes(IsDataCompact: False, TestCas 1.06 3151.39 3344.25
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromReader(M 1.06 21684.42 23004.61
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromStr 1.06 24011.45 25441.16
System.Text.Json.Tests.Perf_Segment.ReadSingleSegmentSequenceByN(numberOfBytes: 1.06 61536.18 65197.38
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromStream( 1.06 767.15 812.49
System.Text.Json.Tests.Perf_Reader.ReadReturnBytes(IsDataCompact: False, TestCas 1.06 7179.94 7600.08
System.Text.Json.Serialization.Tests.ReadJson<HashSet>.DeserializeFromRe 1.06 12052.22 12732.57
System.Text.Json.Serialization.Tests.ReadMissingAndCaseInsensitive.Cas 1.06 1144.98 1209.53
System.Text.Json.Serialization.Tests.ReadJson<HashSet>.DeserializeFromSt 1.06 10647.92 11246.94
System.Text.Json.Serialization.Tests.ReadJson<Dictionary<String, String>>.Deseri 1.06 18923.10 19982.95
System.Text.Json.Serialization.Tests.ReadMissingAndCaseInsensitive.Cas 1.06 1146.40 1210.37
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromUtf8Byte 1.06 30646.49 32340.16
System.Text.Json.Serialization.Tests.ReadJson<ImmutableSortedDictionary<String, 1.05 66385.49 70033.03
System.Text.Json.Serialization.Tests.ReadJson.Deseri 1.05 572.91 604.03
System.Text.Json.Serialization.Tests.ReadJson<ImmutableDictionary<String, String 1.05 41432.18 43665.75
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromUtf 1.05 22644.35 23839.79
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromStream(M 1.05 19279.93 20282.41
System.Text.Json.Tests.Perf_Segment.ReadSingleSegmentSequenceByN(numberOfBytes: 1.05 6210.89 6527.35
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromStr 1.05 23334.47 24504.44
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromUtf8Byte 1.05 29657.21 31103.14
System.Text.Json.Serialization.Tests.ReadJson<ImmutableSortedDictionary<String, 1.05 61311.04 64254.30
System.Text.Json.Serialization.Tests.ReadJson<Dictionary<String, String>>.Deseri 1.05 15576.58 16319.58
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromUtf 1.05 22347.23 23409.13
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromStream(M 1.05 19415.31 20326.00
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromStr 1.05 23399.71 24487.90
System.Text.Json.Tests.Perf_Reader.ReadSpanEmptyLoop(IsDataCompact: True, TestCa 1.05 549.56 575.10
System.Text.Json.Tests.Perf_Reader.ReadSpanEmptyLoop(IsDataCompact: False, TestC 1.05 9913.06 10373.11
System.Text.Json.Tests.Perf_Segment.ReadSingleSegmentSequenceByN(numberOfBytes: 1.05 629626.25 658716.67
System.Text.Json.Tests.Perf_Reader.ReadSpanEmptyLoop(IsDataCompact: True, TestCa 1.04 40269.90 42063.65
System.Text.Json.Tests.Perf_Segment.ReadSingleSegmentSequenceByN(numberOfBytes: 1.04 62027.01 64788.57
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromString( 1.04 533.04 556.70
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromUtf8Byte 1.04 18738.51 19552.31
System.Text.Json.Serialization.Tests.ReadJson<Dictionary<String, String>>.Deseri 1.04 15391.53 16046.31
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromUtf8Byt 1.04 414.52 431.86
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromStream(Mo 1.04 1468.39 1526.37
System.Text.Json.Serialization.Tests.ReadJson.Deseria 1.04 1219.08 1267.17
System.Text.Json.Serialization.Tests.ReadJson.Deseri 1.04 556.24 577.33
System.Text.Json.Serialization.Tests.ReadJson<HashSet>.DeserializeFromSt 1.04 9667.40 10031.91
System.Text.Json.Tests.Perf_Segment.ReadSingleSegmentSequenceByN(numberOfBytes: 1.04 6257.28 6488.89
System.Text.Json.Serialization.Tests.ReadJson.Deseria 1.04 1146.20 1188.37
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromReader(M 1.04 34270.56 35512.47
System.Text.Json.Tests.Perf_Reader.ReadSpanEmptyLoop(IsDataCompact: True, TestCa 1.04 4071.31 4217.23
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromRea 1.04 30224.77 31293.24
System.Text.Json.Tests.Perf_Segment.ReadMultiSegmentSequenceUsingSpan(segmentSiz 1.04 6396.26 6621.34
System.Text.Json.Tests.Perf_Segment.ReadMultiSegmentSequence(segmentSize: 8192, 1.03 645042.00 667544.56
System.Text.Json.Tests.Perf_Reader.ReadMultiSpanSequenceEmptyLoop(IsDataCompact: 1.03 2942.93 3042.59
System.Text.Json.Tests.Perf_Reader.ReadSingleSpanSequenceEmptyLoop(IsDataCompact 1.03 826.01 853.82
System.Text.Json.Tests.Perf_Reader.ReadReturnBytes(IsDataCompact: True, TestCase 1.03 51556.49 53245.30
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromStr 1.03 24904.35 25719.07
System.Text.Json.Tests.Perf_Reader.ReadReturnBytes(IsDataCompact: False, TestCas 1.03 11716.77 12098.85
System.Text.Json.Serialization.Tests.ReadJson.Deseriali 1.03 262059.70 270598.60
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromUtf8Bytes 1.03 1135.73 1172.56
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromReader(M 1.03 21931.73 22635.94
System.Text.Json.Tests.Perf_Reader.ReadSpanEmptyLoop(IsDataCompact: False, TestC 1.03 2707.95 2794.06
System.Text.Json.Tests.Perf_Reader.ReadSpanEmptyLoop(IsDataCompact: False, TestC 1.03 62192.98 64146.71
System.Text.Json.Tests.Perf_Reader.ReadMultiSpanSequenceEmptyLoop(IsDataCompact: 1.03 3042.88 3136.96
System.Text.Json.Tests.Perf_Reader.ReadSpanEmptyLoop(IsDataCompact: True, TestCa 1.03 2855.79 2941.65
System.Text.Json.Tests.Utf8JsonReaderCommentsTests.Utf8JsonReaderCommentParsing( 1.03 89.87 92.54
System.Text.Json.Serialization.Tests.ReadJson<ImmutableSortedDictionary<String, 1.03 69845.51 71860.85
System.Text.Json.Tests.Utf8JsonReaderCommentsTests.Utf8JsonReaderCommentParsing( 1.03 88.44 90.98
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromString(M 1.03 19359.33 19906.38
System.Text.Json.Serialization.Tests.ReadJson<ImmutableDictionary<String, String 1.03 38764.98 39855.05
System.Text.Json.Tests.Perf_Reader.ReadSingleSpanSequenceEmptyLoop(IsDataCompact 1.03 1852.33 1902.04
System.Text.Json.Tests.Utf8JsonReaderCommentsTests.Utf8JsonReaderCommentParsing( 1.03 114.65 117.69
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromString(M 1.03 30654.80 31461.94
System.Text.Json.Serialization.Tests.ReadJson<ImmutableDictionary<String, String 1.03 37938.46 38929.93
System.Text.Json.Tests.Utf8JsonReaderCommentsTests.Utf8JsonReaderCommentParsing( 1.03 89.65 91.91
System.Text.Json.Serialization.Tests.ReadJson.Deseria 1.02 1510.25 1546.88
System.Text.Json.Tests.Utf8JsonReaderCommentsTests.Utf8JsonReaderCommentParsing( 1.02 106.72 109.25
System.Text.Json.Tests.Utf8JsonReaderCommentsTests.Utf8JsonReaderCommentParsing( 1.02 4623.19 4732.33
System.Text.Json.Tests.Utf8JsonReaderCommentsTests.Utf8JsonReaderCommentParsing( 1.02 564.64 577.47
Faster base/diff Base Median (ns) Diff Median (ns) Modality
System.Text.Json.Tests.Perf_Reader.ReadMultiSpanSequenceEmptyLoop(IsDataCompact: 1.47 230.27 156.17
System.Text.Json.Tests.Perf_Reader.ReadSpanEmptyLoop(IsDataCompact: True, TestCa 1.19 2211.09 1856.30
System.Text.Json.Tests.Perf_Depth.ReadSpanEmptyLoop(Depth: 65) 1.17 2705.15 2308.77
System.Text.Json.Tests.Perf_Reader.ReadReturnBytes(IsDataCompact: False, TestCas 1.16 9238.31 7956.55
System.Text.Json.Tests.Perf_Reader.ReadSpanEmptyLoop(IsDataCompact: False, TestC 1.16 8356.03 7234.52
System.Text.Json.Tests.Perf_Reader.ReadMultiSpanSequenceEmptyLoop(IsDataCompact: 1.11 161.24 144.86
System.Text.Json.Tests.Perf_Reader.ReadReturnBytes(IsDataCompact: False, TestCas 1.11 107.96 97.44
System.Text.Json.Tests.Perf_Reader.ReadSingleSpanSequenceEmptyLoop(IsDataCompact 1.09 11070.39 10113.49
System.Text.Json.Serialization.Tests.ReadJson.Deseri 1.09 327.76 301.44
System.Text.Json.Serialization.Tests.ReadJson<ImmutableSortedDictionary<String, 1.09 68711.29 63243.20
System.Text.Json.Tests.Perf_Reader.ReadSpanEmptyLoop(IsDataCompact: False, TestC 1.08 81.30 75.43
System.Text.Json.Tests.Perf_Segment.ReadMultiSegmentSequenceUsingSpan(segmentSiz 1.08 70753.89 65667.46
System.Text.Json.Tests.Perf_Segment.ReadMultiSegmentSequenceUsingSpan(segmentSiz 1.08 704922.83 654766.06
System.Text.Json.Tests.Perf_Reader.ReadSingleSpanSequenceEmptyLoop(IsDataCompact 1.08 6612.16 6147.21
System.Text.Json.Tests.Perf_Reader.ReadReturnBytes(IsDataCompact: True, TestCase 1.06 83.71 79.21
System.Text.Json.Tests.Perf_Depth.ReadSpanEmptyLoop(Depth: 1) 1.06 70.53 66.74
System.Text.Json.Tests.Perf_Reader.ReadMultiSpanSequenceEmptyLoop(IsDataCompact: 1.05 7926.48 7519.52
System.Text.Json.Serialization.Tests.ReadJson.Deseria 1.05 1760.57 1670.36
System.Text.Json.Tests.Perf_Reader.ReadSpanEmptyLoop(IsDataCompact: True, TestCa 1.05 69.85 66.40
System.Text.Json.Reader.Tests.Perf_Base64.ReadBase64EncodedByteArray_HeavyEscapi 1.05 75.08 71.83
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromStream(Mo 1.04 1555.01 1492.88
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromString(Mode: 1.04 125.37 120.39
System.Text.Json.Tests.Perf_Reader.ReadMultiSpanSequenceEmptyLoop(IsDataCompact: 1.04 4515.35 4350.64
System.Text.Json.Tests.Perf_Reader.ReadSpanEmptyLoop(IsDataCompact: False, TestC 1.04 1634.17 1577.40
System.Text.Json.Tests.Perf_Reader.ReadSpanEmptyLoop(IsDataCompact: True, TestCa 1.04 1051.46 1015.63
System.Text.Json.Serialization.Tests.ReadJson<ImmutableSortedDictionary<String, 1.03 69273.53 66944.95
System.Text.Json.Tests.Perf_Reader.ReadReturnBytes(IsDataCompact: True, TestCase 1.03 3745.75 3621.30
System.Text.Json.Tests.Perf_Segment.ReadMultiSegmentSequence(segmentSize: 4096, 1.03 68862.44 66806.36
System.Text.Json.Tests.Perf_Reader.ReadReturnBytes(IsDataCompact: True, TestCase 1.03 686.11 665.70
System.Text.Json.Serialization.Tests.ReadJson.Deseria 1.03 1136.79 1107.72
System.Text.Json.Serialization.Tests.ReadJson.DeserializeFromString(Mode: 1.02 124.37 121.59

@MihaZupan
Copy link
Member

MihaZupan commented Feb 8, 2023

If it uses platform specific SIMD API for arm/intel I can try to extend it to use S.R.I.Wasm.PackedSimd (which is not complete yet).

The platform-specific bits of the implementation for ASCII bytes are here. The rest of the boilerplate can remain as-is.
It's mainly around differences in how underlying shuffle instructions behave (PSHUFB vs TBL). I am not familiar with WASM SIMD instructions, but I would expect that we can implement something similar.

The code for ASCII chars also has some platform-specific optimizations around how the input can be packed from chars to bytes.

@EgorBo
Copy link
Member

EgorBo commented Feb 16, 2023

Wow, it seems like indeed quite a few benchmarks improved - dotnet/perf-autofiling-issues#12941 nice!

Also:

@cincuranet
Copy link
Contributor

cincuranet commented Feb 16, 2023

@stephentoub
Copy link
Member

Out of curiosity I measured it and it was slower in most cases.

@radekdoulik, could you share the change you measured here? I'm not able to reproduce the regressions you're seeing (at least not the ones I tried).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants