public int GetTweetLength(string text, bool normalize = true) { if (string.IsNullOrEmpty(text)) { return(0); } if (normalize) { MiniList <char> normalized; if (NewSuperNfc.Compose(text, out normalized)) { text = new string(normalized.InnerArray, 0, normalized.Count); // ポインタ使わせろ!! } } var length = text.Length; foreach (var x in this._extractor.ExtractUrls(text)) { length += this.ShortUrlLength - x.Length; } // サロゲートペアを削除 var end = text.Length - 1; for (var i = 0; i < end;) { // char.IsSurrogatePair はインライン化されないじゃん? if (char.IsHighSurrogate(text[i]) && char.IsLowSurrogate(text[i + 1])) { length--; i += 2; } else { i++; } } return(length); }
public static void Run() { if (!File.Exists(testFile)) { DownloadTests(); } var tests = LoadTests(); foreach (var x in tests) { // NFC // c2 == toNFC(c1) == toNFC(c2) == toNFC(c3) // c4 == toNFC(c4) == toNFC(c5) MiniList <char> r1; var s1 = NewSuperNfc.Compose(x[0], out r1) ? ToString(r1) : x[0]; MiniList <char> r2; var s2 = NewSuperNfc.Compose(x[1], out r2) ? ToString(r2) : x[1]; MiniList <char> r3; var s3 = NewSuperNfc.Compose(x[2], out r3) ? ToString(r3) : x[2]; MiniList <char> r4; var s4 = NewSuperNfc.Compose(x[3], out r4) ? ToString(r4) : x[3]; MiniList <char> r5; var s5 = NewSuperNfc.Compose(x[4], out r5) ? ToString(r5) : x[4]; if (!(s1 == x[1] && s2 == x[1] && s3 == x[1] && s4 == x[3] && s5 == x[3])) { Debugger.Break(); } } var stopwatch = new Stopwatch(); const int ntimes = #if DEBUG 100 // Debug ビルドだと遅すぎて待ってるのだるい #else 300 #endif ; stopwatch.Start(); for (var i = 0; i < ntimes; i++) { foreach (var x in tests) { foreach (var y in x) { MiniList <char> result; if (NewSuperNfc.Compose(y, out result)) { ToString(result); } } } } stopwatch.Stop(); Console.WriteLine("ToriatamaText.UnicodeNormalization: {0}", stopwatch.Elapsed); stopwatch.Restart(); for (var i = 0; i < ntimes; i++) { foreach (var x in tests) { foreach (var y in x) { y.Normalize(); } } } stopwatch.Stop(); Console.WriteLine("String.Normalize: {0}", stopwatch.Elapsed); }