回答編集履歴

1

CurrentCulture orz

2022/09/22 14:19

投稿

TN8001
TN8001

スコア9326

test CHANGED
@@ -1,18 +1,26 @@
1
- `ReadOnlySpan<char>`にしだけで3桁速くなりました!!?
1
+ ### 更新 1万字超えため元回答と置き換えました
2
- [ReadOnlySpan<T> 構造体 (System) | Microsoft Learn](https://learn.microsoft.com/ja-jp/dotnet/api/system.readonlyspan-1)
3
2
 
3
+ わかりました。`StringComparison`の問題でした(基本のはずなのですが失念しておりました^^;
4
- | Method | N | Mean | Error | StdDev | Median | Ratio |
4
+ [StringComparison 列挙型 (System) | Microsoft Learn](https://learn.microsoft.com/ja-jp/dotnet/api/system.stringcomparison)
5
- |--------- |----- |---------------:|--------------:|--------------:|---------------:|------:|
6
- | Original | 100 | 654.403 us | 3.6567 us | 3.4205 us | 654.070 us | 1.000 |
7
- | ROS | 100 | 4.956 us | 0.0229 us | 0.0203 us | 4.949 us | 0.008 |
8
- | | | | | | | |
9
- | Original | 500 | 19,422.762 us | 481.3766 us | 1,419.3499 us | 18,577.419 us | 1.000 |
10
- | ROS | 500 | 38.692 us | 0.2521 us | 0.2358 us | 38.617 us | 0.002 |
11
- | | | | | | | |
12
- | Original | 1000 | 129,976.638 us | 1,336.7157 us | 1,250.3647 us | 130,517.825 us | 1.000 |
13
- | ROS | 1000 | 112.245 us | 0.4782 us | 0.4473 us | 112.028 us | 0.001 |
5
+ [.NET での文字列の比較に関するベスト プラクティス | Microsoft Learn](https://learn.microsoft.com/ja-jp/dotnet/standard/base-types/best-practices-strings)
14
6
 
15
- 「ほんとかい?」って気がするんですが、なんか間違ってすかね??
7
+ `StringComparison.Ordinal`らば今より100~1000倍は速くした。
8
+ それでも`ReadOnlySpan`のほうが速いことは確かなので、`ROS`を使えるなら使ったほうがいいでしょう^^
9
+
10
+ | Method | N | Mean | Error | StdDev | Ratio |
11
+ |---------------- |----- |---------------:|--------------:|--------------:|------:|
12
+ | Original | 100 | 693.671 us | 13.8602 us | 12.2867 us | 1.000 |
13
+ | OriginalOrdinal | 100 | 6.695 us | 0.0434 us | 0.0385 us | 0.010 |
14
+ | ROS | 100 | 5.053 us | 0.0245 us | 0.0217 us | 0.007 |
15
+ | | | | | | |
16
+ | Original | 500 | 20,997.678 us | 440.4404 us | 1,298.6484 us | 1.000 |
17
+ | OriginalOrdinal | 500 | 47.985 us | 0.9310 us | 0.8253 us | 0.002 |
18
+ | ROS | 500 | 39.873 us | 0.2115 us | 0.1979 us | 0.002 |
19
+ | | | | | | |
20
+ | Original | 1000 | 139,483.870 us | 1,282.5145 us | 1,136.9157 us | 1.000 |
21
+ | OriginalOrdinal | 1000 | 131.865 us | 1.2881 us | 1.0757 us | 0.001 |
22
+ | ROS | 1000 | 117.974 us | 2.3328 us | 2.3957 us | 0.001 |
23
+
16
24
  ```cs
17
25
  using BenchmarkDotNet.Attributes;
18
26
  using BenchmarkDotNet.Running;
@@ -36,7 +44,10 @@
36
44
  public int Original() => GetCharIndex(data, N - 1, N - 1);
37
45
 
38
46
  [Benchmark]
47
+ public int OriginalOrdinal() => GetCharIndex2(data, N - 1, N - 1);
48
+
49
+ [Benchmark]
39
- public int ROS() => GetCharIndex2(data, N - 1, N - 1);
50
+ public int ROS() => GetCharIndex3(data, N - 1, N - 1);
40
51
 
41
52
  int GetCharIndex(string text, int line, int col)
42
53
  {
@@ -64,7 +75,33 @@
64
75
  return begin + col;
65
76
  }
66
77
 
78
+ int GetCharIndex2(string text, int line, int col)
79
+ {
80
+ string code = "\r\n";
81
+ int inLine = line;
82
+
83
+ int begin = 0;
84
+ for (int i = 0; true; i++)
85
+ {
86
+ if (line == 0)
87
+ {
88
+ if (inLine != 0)
89
+ begin += code.Length - 1;
90
+ break;
91
+ }
92
+ begin = text.IndexOf(code, begin, StringComparison.Ordinal);
93
+ if (begin == -1)
94
+ {
95
+ return -1;
96
+ }
97
+ line--;
98
+ begin++;
99
+ }
100
+
101
+ return begin + col;
102
+ }
103
+
67
- int GetCharIndex2(ReadOnlySpan<char> text, int line, int col)
104
+ int GetCharIndex3(ReadOnlySpan<char> text, int line, int col)
68
105
  {
69
106
  var code = "\r\n".AsSpan();
70
107
  var inLine = line;
@@ -105,37 +142,45 @@
105
142
 
106
143
  BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19043.2006/21H1/May2021Update)
107
144
  Intel Core i7 CPU 920 2.67GHz (Nehalem), 1 CPU, 8 logical and 4 physical cores
108
- .NET SDK=7.0.100-preview.3.22179.4
145
+ .NET SDK=7.0.100-rc.1.22431.12
109
146
  [Host] : .NET 6.0.9 (6.0.922.41905), X64 RyuJIT SSE4.2
110
147
  DefaultJob : .NET 6.0.9 (6.0.922.41905), X64 RyuJIT SSE4.2
111
148
 
112
149
 
113
- | Method | N | Mean | Error | StdDev | Median | Ratio |
150
+ | Method | N | Mean | Error | StdDev | Ratio |
114
- |--------- |----- |---------------:|--------------:|--------------:|---------------:|------:|
151
+ |---------------- |----- |---------------:|--------------:|--------------:|------:|
152
+ | Original | 100 | 693.671 us | 13.8602 us | 12.2867 us | 1.000 |
115
- | Original | 100 | 654.403 us | 3.6567 us | 3.4205 us | 654.070 us | 1.000 |
153
+ | OriginalOrdinal | 100 | 6.695 us | 0.0434 us | 0.0385 us | 0.010 |
116
- | ROS | 100 | 4.956 us | 0.0229 us | 0.0203 us | 4.949 us | 0.008 |
154
+ | ROS | 100 | 5.053 us | 0.0245 us | 0.0217 us | 0.007 |
117
- | | | | | | | |
155
+ | | | | | | |
118
- | Original | 500 | 19,422.762 us | 481.3766 us | 1,419.3499 us | 18,577.419 us | 1.000 |
156
+ | Original | 500 | 20,997.678 us | 440.4404 us | 1,298.6484 us | 1.000 |
157
+ | OriginalOrdinal | 500 | 47.985 us | 0.9310 us | 0.8253 us | 0.002 |
119
- | ROS | 500 | 38.692 us | 0.2521 us | 0.2358 us | 38.617 us | 0.002 |
158
+ | ROS | 500 | 39.873 us | 0.2115 us | 0.1979 us | 0.002 |
120
- | | | | | | | |
159
+ | | | | | | |
121
- | Original | 1000 | 129,976.638 us | 1,336.7157 us | 1,250.3647 us | 130,517.825 us | 1.000 |
160
+ | Original | 1000 | 139,483.870 us | 1,282.5145 us | 1,136.9157 us | 1.000 |
161
+ | OriginalOrdinal | 1000 | 131.865 us | 1.2881 us | 1.0757 us | 0.001 |
122
- | ROS | 1000 | 112.245 us | 0.4782 us | 0.4473 us | 112.028 us | 0.001 |
162
+ | ROS | 1000 | 117.974 us | 2.3328 us | 2.3957 us | 0.001 |
123
163
 
124
164
  // * Warnings *
125
165
  MultimodalDistribution
126
- CharIndex.Original: Default -> It seems that the distribution is bimodal (mValue = 3.57)
166
+ CharIndex.Original: Default -> It seems that the distribution is bimodal (mValue = 3.4)
127
167
 
128
168
  // * Hints *
129
169
  Outliers
170
+ CharIndex.Original: Default -> 1 outlier was removed (750.32 us)
171
+ CharIndex.OriginalOrdinal: Default -> 1 outlier was removed (7.19 us)
130
- CharIndex.ROS: Default -> 1 outlier was removed (5.06 us)
172
+ CharIndex.ROS: Default -> 1 outlier was removed (5.33 us)
173
+ CharIndex.OriginalOrdinal: Default -> 1 outlier was removed (51.15 us)
174
+ CharIndex.Original: Default -> 1 outlier was removed (143.96 ms)
175
+ CharIndex.OriginalOrdinal: Default -> 2 outliers were removed (137.41 us, 139.30 us)
176
+ CharIndex.ROS: Default -> 1 outlier was removed (127.26 us)
131
177
  ```
132
- ~~ヘボPCではずかしいw~~
133
178
 
134
179
  ---
135
180
 
136
181
  > インデックスが大きくなっても処理速度が極端に遅くなったりすることがないような実装はありますか?
137
182
 
138
- 想像よりもかなり遅いですね。。。(1万行にしたら全然返ってこなくなりました^^;
183
+ ~~想像よりもかなり遅いですね。。。(1万行にしたら全然返ってこなくなりました^^;~~
139
184
 
140
185
  行数もわからずノーヒントだったら、頭から探していくしかないような。
141
186