{"id":347696,"date":"2023-05-20T09:00:26","date_gmt":"2023-05-20T09:00:26","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=347696"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=347696","title":{"rendered":"<span>\u0411\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0438 \u0438 \u0446\u0438\u043a\u043b\u044b: Replace, Split \u0438 Substring<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<p>\u0423\u0432\u0430\u0436\u0430\u0435\u043c\u044b\u0435 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u0438, \u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0445\u043e\u0447\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043e \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u0442\u0435\u0441\u0442\u0430\u0445 \u0441\u043e \u0441\u0442\u0440\u043e\u043a\u0430\u043c\u0438 \u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0441\u0432\u043e\u0438 \u0432\u044b\u0432\u043e\u0434\u044b. \u0422\u0435\u0441\u0442\u044b \u0441\u0434\u0435\u043b\u0430\u043d\u044b \u043d\u0430 .net 7.<\/p>\n<p>\u0412\u0441\u0435 \u043a\u043e\u0434\u044b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0434\u043b\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u0435\u043d\u0438\u044f \u043d\u043e \u043e\u0442\u043c\u0435\u0447\u0443, \u0447\u0442\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u0432\u0441\u0435\u0433\u043e \u0443\u0434\u0438\u0432\u0438\u043b\u0438 \u0446\u0438\u043a\u043b\u044b.   <\/p>\n<p>\u041f\u0440\u043e \u0441\u0442\u0440\u043e\u043a\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e \u043d\u0435\u043c\u0430\u043b\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0443\u0433\u043b\u0443\u0431\u043b\u044f\u0442\u044c\u0441\u044f \u0432 \u0438\u0445 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u043d\u0435 \u0431\u0443\u0434\u0443, \u043b\u0438\u0448\u044c \u043d\u0430\u043f\u043e\u043c\u043d\u044e, \u0447\u0442\u043e \u0441\u0442\u0440\u043e\u043a\u0438 \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u043c\u0438 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0443\u0445\u0438\u0449\u0440\u0435\u043d\u0438\u0439.<\/p>\n<p>\u0412\u0441\u0435 \u0442\u0435\u0441\u0442\u044b \u0441\u0434\u0435\u043b\u0430\u043d\u044b \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c BenchmarkDotNet, \u0442\u0430\u043a \u0447\u0442\u043e \u043a\u0430\u0436\u0434\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0432\u043e\u0438 \u0432\u044b\u0432\u043e\u0434\u044b.<\/p>\n<p>\u0425\u043e\u0447\u0435\u0442\u0441\u044f \u043d\u0430\u0447\u0430\u0442\u044c \u0441 string.Replace, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430\u043c\u0438, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e:<\/p>\n<pre><code class=\"cs\">    [Benchmark]     public string Replace()     {         return Content.Replace(' ', ',');     }<\/code><\/pre>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0438 \u0447\u0430\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u00ab\u043d\u0430 \u0441\u043a\u043e\u0440\u0443\u044e \u0440\u0443\u043a\u0443\u00bb \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0442\u043e\u0436\u0435 \u043f\u0440\u043e\u0441\u0442 \u0438 \u043e\u0434\u043d\u043e\u0441\u0442\u0440\u043e\u0447\u0435\u043d:<\/p>\n<pre><code class=\"cs\">    [Benchmark]     public string Join()     {         return string.Join(',', Content.Split(' '));     }<\/code><\/pre>\n<p>\u041f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u0432 string.Join \u0438 string.Split \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 ReadOnlySpan \u0438 \u0432 \u0446\u0435\u043b\u043e\u043c \u0432\u0440\u043e\u0434\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e, \u0442\u0430\u043a \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0441\u043e \u0441\u0442\u0435\u043a\u043e\u043c. \u041a\u0441\u0442\u0430\u0442\u0438, \u0435\u0441\u043b\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435 string.Split(&#8216; &nbsp;&#8216;, &#8216;.&#8217;), \u0442\u043e \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0437\u043a\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0443\u0431\u0440\u0430\u0442\u044c \u0442\u043e\u0447\u043a\u0438.<\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 Regex:<\/p>\n<pre><code class=\"cs\">    [Benchmark]     public string Base_Regex()     {         return Regex.Replace(Content, @\"\\s+\", \",\", RegexOptions.Compiled);     }<\/code><\/pre>\n<p>\u0418 \u0435\u0433\u043e \u043d\u043e\u0432\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f:<\/p>\n<pre><code class=\"cs\">    [GeneratedRegex(\"\\\\s+\")]     private static partial Regex GeneratedRegexReplace();      [Benchmark]     public string Generated_Regex()     {         return GeneratedRegexReplace().Replace(Content, \",\");     }<\/code><\/pre>\n<p>\u041e\u0442\u043c\u0435\u0447\u0443 \u0442\u043e\u0442 \u0444\u0430\u043a\u0442, \u0447\u0442\u043e \u0432 GeneratedRegex \u043f\u043e \u0434\u0435\u0444\u043e\u043b\u0442\u0443 RegexOptions.Compiled \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f, \u0430 \u043f\u043e\u0442\u043e\u043c\u0443 \u043d\u0435\u0442 \u0441\u043c\u044b\u0441\u043b\u0430 \u0435\u0433\u043e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c.&nbsp;<\/p>\n<p>\u041f\u0440\u0438\u0448\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0431\u043e\u0440\u0430, \u043d\u043e \u0432 \u0434\u0432\u0443\u0445 \u0432\u0430\u0440\u0438\u0430\u0446\u0438\u044f\u0445. \u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c:<\/p>\n<pre><code class=\"cs\">    [Benchmark]     public string Char_NewString()     {         char[] chars = Content.ToCharArray();         for (int i = 0; i &lt; chars.Length; i++)         {             if (char.IsWhiteSpace(chars[i]))             {                 chars[i] = ',';             }         }          return new string(chars);     }<\/code><\/pre>\n<p>\u0418 \u0432\u0442\u043e\u0440\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0431\u043e\u043b\u0435\u0435 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 for (\u0440\u0430\u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 while \u043d\u043e \u0441 \u043f\u0440\u0438\u044f\u0442\u043d\u044b\u043c \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435\u043c):<\/p>\n<pre><code class=\"cs\">    [Benchmark]     public string Char_NewString_FastFor()     {         char[] chars = Content.ToCharArray();         for (int i = 0, length = chars.Length; i &lt; length; i++)         {             if (char.IsWhiteSpace(chars[i]))             {                 chars[i] = ',';             }         }          return new string(chars);     }<\/code><\/pre>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u043e\u0431\u044b\u0447\u043d\u044b\u043c Span \u0432 \u0432\u0435\u0440\u0441\u0438\u0438 new string(chars) \u0438 string.Concat:<\/p>\n<pre><code class=\"cs\">    [Benchmark]     public string Span_NewString()     {         Span&lt;char&gt; chars = new Span&lt;char&gt;(Content.ToCharArray());         for (int i = 0; i &lt; chars.Length; i++)         {             if (char.IsWhiteSpace(chars[i]))             {                 chars[i] = ',';             }         }          return new string(chars);     }<\/code><\/pre>\n<p>\u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e \u0432 \u043f\u043e\u043b\u043d\u043e\u043c \u043b\u0438\u0441\u0442\u0438\u043d\u0433\u0435 \u0432\u044b \u043d\u0430\u0439\u0434\u0435\u0442\u0435 \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 unsafe ReadOnlySpan, \u043f\u0440\u044f\u043c\u0443\u044e \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0441\u0442\u0440\u043e\u043a\u0438 (\u0438\u043c\u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0434 \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u043c:)) \u0438 \u0440\u0430\u043d\u0435\u0435 \u043c\u043d\u043e\u044e \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u043d\u043e \u0432\u043f\u043e\u043b\u043d\u0435 \u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0441 string.Create().<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cs\">using BenchmarkDotNet.Attributes; using System.Runtime.InteropServices; using System.Text.RegularExpressions;  namespace Benchmarks.Benchmarks;  [MemoryDiagnoser(false)] public partial class ReplaceString {     private const string Content =         \"Hello World! Add new line. Ok. Substring allocates a new string object on the heap and performs a full copy of the extracted text.\" +         \"String manipulation is a performance bottleneck for many programs. Many APIs that accept strings also have overloads that accept a ReadOnlySpan&lt;System.Char&gt; argument.\" +         \"When such overloads are available, you can improve performance by calling AsSpan instead of Substring.\";      [Benchmark]     public string Replace()     {         return Content.Replace(' ', ',');     }      [Benchmark]     public string Join()     {         return string.Join(',', Content.Split(' '));     }      [Benchmark]     public string Base_Regex()     {         return Regex.Replace(Content, @\"\\s+\", \",\", RegexOptions.Compiled);     }      [GeneratedRegex(\"\\\\s+\")]     private static partial Regex GeneratedRegexReplace();      [Benchmark]     public string Generated_Regex()     {         return GeneratedRegexReplace().Replace(Content, \",\");     }      [Benchmark]     public string Char_NewString()     {         char[] chars = Content.ToCharArray();         for (int i = 0; i &lt; chars.Length; i++)         {             if (char.IsWhiteSpace(chars[i]))             {                 chars[i] = ',';             }         }          return new string(chars);     }      [Benchmark]     public string Char_NewString_FastFor()     {         char[] chars = Content.ToCharArray();         for (int i = 0, length = chars.Length; i &lt; length; i++)         {             if (char.IsWhiteSpace(chars[i]))             {                 chars[i] = ',';             }         }          return new string(chars);     }      [Benchmark]     public string Span_NewString()     {         Span&lt;char&gt; chars = new Span&lt;char&gt;(Content.ToCharArray());         for (int i = 0; i &lt; chars.Length; i++)         {             if (char.IsWhiteSpace(chars[i]))             {                 chars[i] = ',';             }         }          return new string(chars);     }      [Benchmark]     public string Span_Concat()     {         Span&lt;char&gt; chars = new Span&lt;char&gt;(Content.ToCharArray());         for (int i = 0; i &lt; chars.Length; i++)         {             if (char.IsWhiteSpace(chars[i]))             {                 chars[i] = ',';             }         }          return string.Concat(chars.ToArray());     }      [Benchmark]     public string Char_Concat()     {         char[] chars = Content.ToCharArray();         for (int i = 0; i &lt; chars.Length; i++)         {             if (char.IsWhiteSpace(chars[i]))             {                 chars[i] = ',';             }         }          return string.Concat(chars);     }      [Benchmark]     public string Unsafe_ReadOnlySpan_NewString()     {         ReadOnlySpan&lt;char&gt; chars = Content.AsSpan();         for (int i = 0; i &lt; chars.Length; i++)         {             if (!char.IsWhiteSpace(chars[i]))             {                 continue;             }              unsafe             {                 fixed (char* baseChar = chars)                 {                     char* newChar = baseChar + i;                     *newChar = ',';                 }             }         }          return new string(chars);     }      [Benchmark]     public string Unsafe_ReadOnlySpan_NewString_Foreach()     {         int i = 0;          ReadOnlySpan&lt;char&gt; chars = Content.AsSpan();         foreach (char @char in chars)         {             ++i;             if (!char.IsWhiteSpace(@char))             {                 continue;             }              unsafe             {                 fixed (char* baseChar = chars)                 {                     char* newChar = baseChar + i;                     *newChar = ',';                 }             }         }          return new string(chars);     }      [Benchmark]     public string Unsafe_String()     {         for (int i = 0; i &lt; Content.Length; i++)         {             if (!char.IsWhiteSpace(Content[i]))             {                 continue;             }              unsafe             {                 fixed (char* baseChar = Content)                 {                     char* newChar = baseChar + i;                     *newChar = ',';                 }             }         }          return Content;     }      [Benchmark]     public string Unsafe_String_Foreach()     {         int i = 0;         foreach (char @char in Content)         {             ++i;             if (!char.IsWhiteSpace(@char))             {                 continue;             }              unsafe             {                 fixed (char* baseChar = Content)                 {                     char* newChar = baseChar + i;                     *newChar = ',';                 }             }         }          return Content;     }      [Benchmark]     public string Marshal_Span_ToString()     {         Span&lt;char&gt; chars = MemoryMarshal.CreateSpan(ref MemoryMarshal.GetReference(Content.AsSpan()), Content.Length);         for (int i = 0; i &lt; chars.Length; i++)         {             if (char.IsWhiteSpace(chars[i]))             {                 chars[i] = ',';             }         }          return chars.ToString();     }      [Benchmark]     public string Marshal_Span_NewString()     {         Span&lt;char&gt; chars = MemoryMarshal.CreateSpan(ref MemoryMarshal.GetReference(Content.AsSpan()), Content.Length);         for (int i = 0; i &lt; chars.Length; i++)         {             if (char.IsWhiteSpace(chars[i]))             {                 chars[i] = ',';             }         }          return new string(chars);     }      [Benchmark]     public string String_Create()     {         string result = string.Create(Content.Length, Content, (chars, buffer) =&gt;         {             for (int i = 0; i &lt; chars.Length; i++)             {                 chars[i] = buffer[i];                 if (char.IsWhiteSpace(chars[i]))                 {                     chars[i] = ',';                 }             }         });                  return result;     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u0430\u043c\u043e\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0435, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e6f\/5dc\/662\/e6f5dc6628df1b9de4641b6ab5e9fd6b.jpg\" width=\"732\" height=\"308\"><\/figure>\n<p>\u041a\u0430\u043a \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0432\u043f\u043e\u043b\u043d\u0435 \u0443\u0434\u0430\u0447\u0435\u043d, \u043d\u043e \u043d\u0435 \u0432\u043e \u0432\u0441\u0435\u0445 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044f\u0445, \u0442\u0430\u043a \u043a\u0430\u043a \u043f\u0430\u043c\u044f\u0442\u044c \u0432\u0441\u0435 \u0436\u0435 \u0440\u0430\u0441\u0445\u043e\u0434\u0443\u0435\u0442, \u0430 \u0432\u043e\u0442 unsafe \u043d\u0435\u0442, \u0447\u0442\u043e \u0432 \u0446\u0435\u043b\u043e\u043c \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e, \u043d\u043e \u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043a\u0440\u0430\u0439\u043d\u0435 \u0445\u0440\u043e\u043c\u0430\u0435\u0442.<\/p>\n<p>\u0421\u0442\u043e\u0438\u0442 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 for \u0438 \u0431\u043e\u043b\u0435\u0435 \u00ab\u043d\u043e\u0432\u0443\u044e\u00bb \u0432\u0435\u0440\u0441\u0438\u044e, \u0447\u0442\u043e \u043f\u043e \u0444\u0430\u043a\u0442\u0443 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0441\u0430\u0445\u0430\u0440, \u043d\u043e \u0432\u0441\u0435 \u0436\u0435 \u0440\u0430\u0437\u043d\u0438\u0446\u0430 \u0432 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0435\u0441\u0442\u044c.<\/p>\n<p>\u041a\u0430\u043a \u0438 \u0431\u044b\u043b\u043e \u0432\u043e \u0432\u0441\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0430, Regex \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0443\u0434\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u043e \u0441\u0442\u0440\u043e\u043a\u0430\u043c\u0438 \u0432 \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u043c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0435, \u0445\u043e\u0442\u044c \u0432\u043f\u043e\u043b\u043d\u0435 \u043a\u0440\u0430\u0441\u0438\u0432 \u043d\u0430 \u0432\u0438\u0434. \u041b\u0438\u0447\u043d\u043e \u0434\u043b\u044f \u043c\u0435\u043d\u044f \u0438\u043d\u0442\u0440\u0438\u0433\u0430 \u0431\u044b\u043b\u0430 \u0432 foreach \u0438 \u0432\u0441\u0435 \u0436\u0435 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 for \u0434\u043e \u0441\u0438\u0445 \u043f\u043e\u0440 \u0443\u0434\u0430\u0447\u043d\u044b\u0439 \u0432\u044b\u0431\u043e\u0440, \u0447\u0442\u043e \u0431\u044b \u0442\u0430\u043a \u043d\u0438 \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u0438 \u043f\u0440\u043e \u00ab\u044d\u0442\u043e \u0443\u0436\u0435 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043e\u00bb.<\/p>\n<p>\u0412 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u043c \u0446\u0438\u0444\u0440\u044b \u0432\u043f\u043e\u043b\u043d\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0435.<\/p>\n<p>\u041f\u0440\u0438\u0448\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0447\u0442\u043e \u0442\u0430\u043c \u0441\u043e Split?<\/p>\n<p>\u0412 \u0446\u0435\u043b\u043e\u043c \u0438\u0434\u0435\u0438 \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432, \u043d\u043e \u0441 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u043c\u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f\u043c\u0438 \u0438\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u043c\u0438. \u0412 \u043f\u043e\u043b\u043d\u043e\u043c \u043b\u0438\u0441\u0442\u0438\u043d\u0433\u0435 \u043c\u043e\u0436\u043d\u043e \u0433\u043b\u044f\u043d\u0443\u0442\u044c \u0447\u0442\u043e \u043a\u0430\u043a \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043b\u043e\u0441\u044c, \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0442\u043c\u0435\u0447\u0443, \u0447\u0442\u043e \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0437\u043a\u0438 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0433\u043e string.Split() \u043a\u0440\u0430\u0439\u043d\u0435 \u0443\u0434\u0438\u0432\u0438\u043b\u0438 \u0440\u0430\u0437\u043d\u0438\u0446\u0435 \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u0445 \u0442\u0435\u0441\u0442\u0430, \u0430 \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u043c\u0430\u0441\u0441\u0438\u0432\u0430\u043c\u0438 \u0431\u044b\u043b\u0430 \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e \u043d\u0430\u0439\u0434\u0435\u043d\u0430 \u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u043e\u0440\u0430\u0445 \u0418\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0430, \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e \u0434\u043e\u043f\u0438\u0441\u0430\u043d\u0430 \u0441\u0432\u043e\u0438\u043c\u0438 \u0441\u0438\u043b\u0430\u043c\u0438.<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cs\">using BenchmarkDotNet.Attributes; using System.Text; using System.Text.RegularExpressions;  namespace Benchmarks.Benchmarks;  [MemoryDiagnoser(false)] public partial class SplitString {     private const string Content =         \"Hello World! Add new line. Ok. Substring allocates a new string object on the heap and performs a full copy of the extracted text.\" +         \"String manipulation is a performance bottleneck for many programs. Many APIs that accept strings also have overloads that accept a ReadOnlySpan&lt;System.Char&gt; argument.\" +         \"When such overloads are available, you can improve performance by calling AsSpan instead of Substring.\";      [Benchmark]     public string[] Split_Default()     {         return Content.Split();     }      [Benchmark]     public string[] Split_Whitespace()     {         return Content.Split(' ');     }      [Benchmark]     public string[] Split_Null()     {         return Content.Split(null);     }      [Benchmark]     public string[] Split_NewChar()     {         return Content.Split(new char[0]);     }      [Benchmark]     public string[] Base_Regex()     {         return Regex.Split(Content, \"\\\\s+\", RegexOptions.Compiled);     }      [GeneratedRegex(\"\\\\s+\")]     private static partial Regex GeneratedRegexDefault();      [Benchmark]     public string[] GeneratedRegex()     {         return GeneratedRegexDefault().Split(Content);     }      [Benchmark]     public string[] Array_Indexator()     {         int index = -1;         StringBuilder sb = new(Content.Length);          int elementCount = 0;          string[] strings = new string[Content.Length];         for (int i = 0; i &lt; Content.Length; i++)         {             if (char.IsWhiteSpace(Content[i]))             {                 ++elementCount;                  strings[++index] = sb.ToString();                  sb.Clear();                 continue;             }              sb.Append(Content[i]);         }          Array.Resize(ref strings, elementCount);          return strings;     }      [Benchmark]     public string[] Array_SetValue()     {         int index = -1;         StringBuilder sb = new(Content.Length);          int elementCount = 0;          string[] strings = new string[Content.Length];         for (int i = 0; i &lt; Content.Length; i++)         {             if (char.IsWhiteSpace(Content[i]))             {                 ++elementCount;                  strings.SetValue(sb.ToString(), ++index);                  sb.Clear();                 continue;             }              sb.Append(Content[i]);         }          Array.Resize(ref strings, elementCount);          return strings;     } } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0442\u0435\u0441\u0442\u043e\u0432:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d74\/e3c\/776\/d74e3c7767cefe832844f56d6184417a.jpg\" width=\"544\" height=\"175\"><\/figure>\n<p>\u0422\u0443\u0442 \u044f \u0443\u0434\u0438\u0432\u0438\u043b\u0441\u044f, \u0447\u0442\u043e \u0432\u0440\u043e\u0434\u0435 \u043e\u0434\u043d\u043e\u0442\u0438\u043f\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0437\u043a\u0438, \u0430 \u0432\u0441\u0435 \u0436\u0435 \u0434\u0430\u044e\u0442 \u0440\u0430\u0437\u043d\u044b\u0435 \u044d\u0444\u0444\u0435\u043a\u0442 \u043f\u043e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438. \u041f\u043e\u043d\u044f\u0442\u043d\u043e\u0435 \u0434\u0435\u043b\u043e, \u0447\u0442\u043e \u043b\u0443\u0447\u0448\u0435 \u0432\u0441\u0435\u0433\u043e \u043e\u0431\u044b\u0447\u043d\u044b\u0439 char \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c, \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u044e\u0442\u0441\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u044b \u0437\u0430 \u0441\u0447\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f params, \u043d\u043e \u0432\u0441\u0435 \u0436\u0435 \u0442\u0435\u0441\u0442\u044b \u0435\u0441\u0442\u044c \u0442\u0435\u0441\u0442\u044b, \u043d\u0430\u0434\u043e \u043f\u043e\u0449\u0443\u043f\u0430\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u0442\u043e\u0447\u043d\u043e \u0432\u0441\u0435 \u043f\u043e\u043d\u044f\u0442\u044c.<\/p>\n<p>\u041e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0441 Substring. \u041c\u0435\u0442\u043e\u0434 \u0432\u043f\u043e\u043b\u043d\u0435 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0439, \u0447\u0442\u043e\u0431\u044b \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043e\u0431\u0449\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0435 \u0444\u0430\u043a\u0442\u044b, \u043d\u043e \u043e\u0442\u043c\u0435\u0447\u0443, \u0447\u0442\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0442\u0435\u0441\u0442\u043e\u0432 \u0431\u044b\u043b\u0438 \u0441\u043e\u0431\u0440\u0430\u043d\u044b \u0440\u0430\u0434\u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u00ab\u0410 \u043a\u0430\u043a \u0435\u0449\u0435 \u043c\u043e\u0436\u043d\u043e \u0438 \u0447\u0442\u043e \u044d\u0442\u043e \u0434\u0430\u0441\u0442?\u00bb.<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cs\">using BenchmarkDotNet.Attributes; using System.Runtime.InteropServices; using System.Text; using System.Text.RegularExpressions;  namespace Benchmarks.Benchmarks;  [MemoryDiagnoser(false)] public partial class SubString {     private const string Content =         \"Hello World! Add new line. Ok. Substring allocates a new string object on the heap and performs a full copy of the extracted text.\" +         \"String manipulation is a performance bottleneck for many programs. Many APIs that accept strings also have overloads that accept a ReadOnlySpan&lt;System.Char&gt; argument.\" +         \"When such overloads are available, you can improve performance by calling AsSpan instead of Substring.\";      [Benchmark]     public string Indexator()     {         return Content[6..11];     }      [Benchmark]     public string Substring()     {         return Content.Substring(6, 5);     }      [Benchmark]     public string ReadOnlySpan_ToString()     {         return Content.AsSpan(6, 5).ToString();     }      [Benchmark]     public string ReadOnlySpan_NewString()     {         return new string(Content.AsSpan(6, 5));     }      [Benchmark]     public unsafe string Unsafe()     {         fixed (char* chars = Content)         {             return new string(chars, 6, 5);         }     }      [Benchmark]     public string StringBuilder()     {         StringBuilder sb = new(Content);         return sb.ToString(6, 5);     }      [GeneratedRegex(\"(\\\\w+)\")]     private static partial Regex GeneratedRegexFirst();      [Benchmark]     public string GeneratedRegex_First()     {         Regex match = GeneratedRegexFirst();         return match.Match(Content, 6, 5).Value;     }          [GeneratedRegex(\"^.{6}(.{5}).*$\")]     private static partial Regex GeneratedRegexSecond();      [Benchmark]     public string GeneratedRegex_Second()     {         return GeneratedRegexSecond().Match(Content).Groups[1].Value;     }      [Benchmark]     public string MemoryMarshal_Span_NewString()     {         Span&lt;char&gt; span = MemoryMarshal.CreateSpan(ref MemoryMarshal.GetReference(Content.AsSpan()), Content.Length);         return new string(span.Slice(6, 5));     }      [Benchmark]     public string MemoryMarshal_ReadOnlySpan_NewString()     {         ReadOnlySpan&lt;char&gt; span = MemoryMarshal.CreateReadOnlySpan(ref MemoryMarshal.GetReference(Content.AsSpan()), Content.Length);         return new string(span.Slice(6, 5));     }      [Benchmark]     public string MemoryMarshal_Span_ToString()     {         Span&lt;char&gt; span = MemoryMarshal.CreateSpan(ref MemoryMarshal.GetReference(Content.AsSpan()), Content.Length);         return span.Slice(6, 5).ToString();     }      [Benchmark]     public string MemoryMarshal_ReadOnlySpan_ToString()     {         ReadOnlySpan&lt;char&gt; span = MemoryMarshal.CreateReadOnlySpan(ref MemoryMarshal.GetReference(Content.AsSpan()), Content.Length);         return span.Slice(6, 5).ToString();     } } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0418 \u0441\u0440\u0430\u0437\u0443 \u043a \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u043c:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/7de\/8c6\/932\/7de8c69328d1d7c08092704403a52dca.jpg\" width=\"720\" height=\"240\"><\/figure>\n<p>\u0418\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0439 \u0444\u0430\u043a\u0442 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e, \u0434\u0435\u043b\u0430\u044f \u0442\u0435\u0441\u0442 \u043c\u043d\u043e\u0433\u043e\u043a\u0440\u0430\u0442\u043d\u043e \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u0442\u043e\u0440\u044b \u0447\u0430\u0449\u0435 \u043b\u0438\u0434\u0438\u0440\u0443\u044e\u0442, \u0430 \u043f\u043e\u0442\u043e\u043c\u0443 \u043e\u043d\u0438 \u0432\u043f\u043e\u043b\u043d\u0435 \u043f\u0440\u0438\u0433\u043e\u0434\u043d\u044b \u0434\u043b\u044f \u0437\u0430\u043c\u0435\u043d\u044b \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u043c\u0443 Substring, \u0447\u0442\u043e \u0443\u0434\u0438\u0432\u0438\u043b\u043e.<\/p>\n<p>\u0412\u0441\u0435 \u043a\u043e\u0434\u044b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0434\u043b\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u0435\u043d\u0438\u044f \u043d\u043e \u043e\u0442\u043c\u0435\u0447\u0443, \u0447\u0442\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u0432\u0441\u0435\u0433\u043e \u0443\u0434\u0438\u0432\u0438\u043b\u0438 \u0446\u0438\u043a\u043b\u044b.<\/p>\n<p>\u0414\u043b\u044f \u0441\u0442\u0430\u0440\u0442\u0430 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 for:<\/p>\n<pre><code class=\"cs\">    [Benchmark]     public int For()     {         int sum = 0;         for (int i = 0; i &lt; Items.Length; i++)         {             sum += i;         }          return sum;     }<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043d\u0435 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 for:<\/p>\n<pre><code class=\"cs\">    [Benchmark]     public int New_For()     {         int sum = 0;         for (int i = 0, length = Items.Length; i &lt; length; i++)         {             sum += i;         }          return sum;     }<\/code><\/pre>\n<p>\u0422\u0443\u0442 \u043c\u044b \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u043c, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0438 \u043c\u0438\u043d\u0443\u0441 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430. \u0414\u0430, \u0443\u0432\u044b, c# \u043f\u043e\u043a\u0430 \u043d\u0435 \u0442\u0430\u043a \u0440\u0430\u0437\u0443\u043c\u0435\u043d, \u043a\u0430\u043a \u0445\u043e\u0447\u0435\u0442\u0441\u044f:(<\/p>\n<p>\u041d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0435\u043c \u043f\u0440\u043e \u043e\u0431\u044b\u0447\u043d\u044b\u0439 foreach:<\/p>\n<pre><code class=\"cs\">    [Benchmark]     public int Foreach()     {         int i = 0;          int sum = 0;         foreach (int item in Items)         {             sum += i;             i++;         }          return sum;     }<\/code><\/pre>\n<p>\u0418, \u0431\u0435\u0441\u0441\u043f\u043e\u0440\u043d\u043e, while:<\/p>\n<pre><code class=\"cs\">    [Benchmark]     public int While()     {         int sum = 0;          int i = 0;         while (i &lt; Items.Length)         {             sum += i++;         }          return sum;     }<\/code><\/pre>\n<p>\u0418 \u0432\u0442\u043e\u0440\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0441 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0435\u0439:<\/p>\n<pre><code class=\"cs\">    [Benchmark]     public int New_While()     {         int sum = 0;         int length = Items.Length;          int i = 0;         while (i &lt; length)         {             sum += i++;         }          return sum;     }<\/code><\/pre>\n<p>\u0418 \u0440\u0430\u0434\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0430 List:<\/p>\n<pre><code class=\"cs\">    [Benchmark]     public int List_ForEach()     {         int sum = 0;          int i = 0;         Items.ToList().ForEach(x =&gt;         {             sum += i;             i++;         });          return sum;     }<\/code><\/pre>\n<p>\u0410 \u0442\u0430\u043a\u0436\u0435 Span:<\/p>\n<pre><code class=\"cs\">    [Benchmark]     public int For_Span()     {         Span&lt;int&gt; items = Items.AsSpan();          int sum = 0;         for (int i = 0, length = items.Length; i &lt; length; i++)         {             sum += i;         }          return sum;     }<\/code><\/pre>\n<p>\u0418 ReadOnlySpan:<\/p>\n<pre><code class=\"cs\">    [Benchmark]     public int For_ReadOnlySpan()     {         ReadOnlySpan&lt;int&gt; items = new ReadOnlySpan&lt;int&gt;(Items);          int sum = 0;         for (int i = 0, length = items.Length; i &lt; length; i++)         {             sum += i;         }          return sum;     }<\/code><\/pre>\n<p>\u0412\u0441\u0435 \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u0434\u0430\u0435\u0442 \u043e\u0434\u043d\u043e \u0438 \u0442\u043e \u0436\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u0432\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u043b\u0435\u0433\u043a\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0441\u0432\u043e\u0438\u043c\u0438 \u0441\u0438\u043b\u0430\u043c\u0438.<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cs\">using BenchmarkDotNet.Attributes;  namespace Benchmarks.Benchmarks;  [MemoryDiagnoser(false)] public class Cycles {     private static int[] Items =&gt; Enumerable.Range(1, 10_000).ToArray();      [Benchmark]     public int List_ForEach()     {         int sum = 0;          int i = 0;         Items.ToList().ForEach(x =&gt;         {             sum += i;             i++;         });          return sum;     }      [Benchmark]     public int For_Span()     {         Span&lt;int&gt; items = Items.AsSpan();          int sum = 0;         for (int i = 0, length = items.Length; i &lt; length; i++)         {             sum += i;         }          return sum;     }      [Benchmark]     public int For_ReadOnlySpan()     {         ReadOnlySpan&lt;int&gt; items = new ReadOnlySpan&lt;int&gt;(Items);          int sum = 0;         for (int i = 0, length = items.Length; i &lt; length; i++)         {             sum += i;         }          return sum;     }      [Benchmark]     public int For()     {         int sum = 0;         for (int i = 0; i &lt; Items.Length; i++)         {             sum += i;         }          return sum;     }      [Benchmark]     public int New_For()     {         int sum = 0;         for (int i = 0, length = Items.Length; i &lt; length; i++)         {             sum += i;         }          return sum;     }      [Benchmark]     public int Foreach()     {         int i = 0;          int sum = 0;         foreach (int item in Items)         {             sum += i;             i++;         }          return sum;     }      [Benchmark]     public int While()     {         int sum = 0;          int i = 0;         while (i &lt; Items.Length)         {             sum += i++;         }          return sum;     }       [Benchmark]     public int New_While()     {         int sum = 0;         int length = Items.Length;          int i = 0;         while (i &lt; length)         {             sum += i++;         }          return sum;     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0418\u0442\u043e\u0433 \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u0441\u0430\u043c \u0437\u0430 \u0441\u0435\u0431\u044f:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/7ff\/f22\/c39\/7fff22c390c810a28ab3c8eec7da0e1d.jpg\" width=\"656\" height=\"179\"><\/figure>\n<p>\u041e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043a\u0430\u0436\u0434\u044b\u0439 \u043f\u0440\u043e\u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u043d\u0430 \u0441\u0432\u043e\u0435 \u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u0435 \u0438 \u0440\u0430\u0434\u0438 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u043e\u0432 \ud83d\ude42<\/p>\n<p>\u0412\u0441\u0435\u043c \u0443\u0434\u0430\u0447\u0438 \u0438 \u0434\u043e \u043d\u043e\u0432\u044b\u0445 \u0432\u0441\u0442\u0440\u0435\u0447!<\/p>\n<\/p>\n<\/div>\n<\/div>\n<p> <!----> <!----><\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/736434\/\"> https:\/\/habr.com\/ru\/articles\/736434\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<p>\u0423\u0432\u0430\u0436\u0430\u0435\u043c\u044b\u0435 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u0438, \u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0445\u043e\u0447\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043e \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u0442\u0435\u0441\u0442\u0430\u0445 \u0441\u043e \u0441\u0442\u0440\u043e\u043a\u0430\u043c\u0438 \u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0441\u0432\u043e\u0438 \u0432\u044b\u0432\u043e\u0434\u044b. \u0422\u0435\u0441\u0442\u044b \u0441\u0434\u0435\u043b\u0430\u043d\u044b \u043d\u0430 .net 7.<\/p>\n<p>\u0412\u0441\u0435 \u043a\u043e\u0434\u044b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0434\u043b\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u0435\u043d\u0438\u044f \u043d\u043e \u043e\u0442\u043c\u0435\u0447\u0443, \u0447\u0442\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u0432\u0441\u0435\u0433\u043e \u0443\u0434\u0438\u0432\u0438\u043b\u0438 \u0446\u0438\u043a\u043b\u044b.   <\/p>\n<p>\u041f\u0440\u043e \u0441\u0442\u0440\u043e\u043a\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e \u043d\u0435\u043c\u0430\u043b\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0443\u0433\u043b\u0443\u0431\u043b\u044f\u0442\u044c\u0441\u044f \u0432 \u0438\u0445 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u043d\u0435 \u0431\u0443\u0434\u0443, \u043b\u0438\u0448\u044c \u043d\u0430\u043f\u043e\u043c\u043d\u044e, \u0447\u0442\u043e \u0441\u0442\u0440\u043e\u043a\u0438 \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u043c\u0438 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0443\u0445\u0438\u0449\u0440\u0435\u043d\u0438\u0439.<\/p>\n<p>\u0412\u0441\u0435 \u0442\u0435\u0441\u0442\u044b \u0441\u0434\u0435\u043b\u0430\u043d\u044b \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c BenchmarkDotNet, \u0442\u0430\u043a \u0447\u0442\u043e \u043a\u0430\u0436\u0434\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0432\u043e\u0438 \u0432\u044b\u0432\u043e\u0434\u044b.<\/p>\n<p>\u0425\u043e\u0447\u0435\u0442\u0441\u044f \u043d\u0430\u0447\u0430\u0442\u044c \u0441 string.Replace, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430\u043c\u0438, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e:<\/p>\n<pre><code class=\"cs\">    [Benchmark]     public string Replace()     {         return Content.Replace(' ', ',');     }<\/code><\/pre>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0438 \u0447\u0430\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u00ab\u043d\u0430 \u0441\u043a\u043e\u0440\u0443\u044e \u0440\u0443\u043a\u0443\u00bb \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0442\u043e\u0436\u0435 \u043f\u0440\u043e\u0441\u0442 \u0438 \u043e\u0434\u043d\u043e\u0441\u0442\u0440\u043e\u0447\u0435\u043d:<\/p>\n<pre><code class=\"cs\">    [Benchmark]     public string Join()     {         return string.Join(',', Content.Split(' '));     }<\/code><\/pre>\n<p>\u041f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u0432 string.Join \u0438 string.Split \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 ReadOnlySpan \u0438 \u0432 \u0446\u0435\u043b\u043e\u043c \u0432\u0440\u043e\u0434\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e, \u0442\u0430\u043a \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0441\u043e \u0441\u0442\u0435\u043a\u043e\u043c. \u041a\u0441\u0442\u0430\u0442\u0438, \u0435\u0441\u043b\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435 string.Split(&#8216; &nbsp;&#8216;, &#8216;.&#8217;), \u0442\u043e \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0437\u043a\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0443\u0431\u0440\u0430\u0442\u044c \u0442\u043e\u0447\u043a\u0438.<\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 Regex:<\/p>\n<pre><code class=\"cs\">    [Benchmark]     public string Base_Regex()     {         return Regex.Replace(Content, @\"\\s+\", \",\", RegexOptions.Compiled);     }<\/code><\/pre>\n<p>\u0418 \u0435\u0433\u043e \u043d\u043e\u0432\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f:<\/p>\n<pre><code class=\"cs\">    [GeneratedRegex(\"\\\\s+\")]     private static partial Regex GeneratedRegexReplace();      [Benchmark]     public string Generated_Regex()     {         return GeneratedRegexReplace().Replace(Content, \",\");     }<\/code><\/pre>\n<p>\u041e\u0442\u043c\u0435\u0447\u0443 \u0442\u043e\u0442 \u0444\u0430\u043a\u0442, \u0447\u0442\u043e \u0432 GeneratedRegex \u043f\u043e \u0434\u0435\u0444\u043e\u043b\u0442\u0443 RegexOptions.Compiled \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f, \u0430 \u043f\u043e\u0442\u043e\u043c\u0443 \u043d\u0435\u0442 \u0441\u043c\u044b\u0441\u043b\u0430 \u0435\u0433\u043e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c.&nbsp;<\/p>\n<p>\u041f\u0440\u0438\u0448\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0431\u043e\u0440\u0430, \u043d\u043e \u0432 \u0434\u0432\u0443\u0445 \u0432\u0430\u0440\u0438\u0430\u0446\u0438\u044f\u0445. \u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c:<\/p>\n<pre><code class=\"cs\">    [Benchmark]     public string Char_NewString()     {         char[] chars = Content.ToCharArray();         for (int i = 0; i &lt; chars.Length; i++)         {             if (char.IsWhiteSpace(chars[i]))             {                 chars[i] = ',';             }         }          return new string(chars);     }<\/code><\/pre>\n<p>\u0418 \u0432\u0442\u043e\u0440\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0431\u043e\u043b\u0435\u0435 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 for (\u0440\u0430\u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 while \u043d\u043e \u0441 \u043f\u0440\u0438\u044f\u0442\u043d\u044b\u043c \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435\u043c):<\/p>\n<pre><code class=\"cs\">    [Benchmark]     public string Char_NewString_FastFor()     {         char[] chars = Content.ToCharArray();         for (int i = 0, length = chars.Length; i &lt; length; i++)         {             if (char.IsWhiteSpace(chars[i]))             {                 chars[i] = ',';             }         }          return new string(chars);     }<\/code><\/pre>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u043e\u0431\u044b\u0447\u043d\u044b\u043c Span \u0432 \u0432\u0435\u0440\u0441\u0438\u0438 new string(chars) \u0438 string.Concat:<\/p>\n<pre><code class=\"cs\">    [Benchmark]     public string Span_NewString()     {         Span&lt;char&gt; chars = new Span&lt;char&gt;(Content.ToCharArray());         for (int i = 0; i &lt; chars.Length; i++)         {             if (char.IsWhiteSpace(chars[i]))             {                 chars[i] = ',';             }         }          return new string(chars);     }<\/code><\/pre>\n<p>\u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e \u0432 \u043f\u043e\u043b\u043d\u043e\u043c \u043b\u0438\u0441\u0442\u0438\u043d\u0433\u0435 \u0432\u044b \u043d\u0430\u0439\u0434\u0435\u0442\u0435 \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 unsafe ReadOnlySpan, \u043f\u0440\u044f\u043c\u0443\u044e \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0441\u0442\u0440\u043e\u043a\u0438 (\u0438\u043c\u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0434 \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u043c:)) \u0438 \u0440\u0430\u043d\u0435\u0435 \u043c\u043d\u043e\u044e \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u043d\u043e \u0432\u043f\u043e\u043b\u043d\u0435 \u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0441 string.Create().<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cs\">using BenchmarkDotNet.Attributes; using System.Runtime.InteropServices; using System.Text.RegularExpressions;  namespace Benchmarks.Benchmarks;  [MemoryDiagnoser(false)] public partial class ReplaceString {     private const string Content =         \"Hello World! Add new line. Ok. Substring allocates a new string object on the heap and performs a full copy of the extracted text.\" +         \"String manipulation is a performance bottleneck for many programs. Many APIs that accept strings also have overloads that accept a ReadOnlySpan&lt;System.Char&gt; argument.\" +         \"When such overloads are available, you can improve performance by calling AsSpan instead of Substring.\";      [Benchmark]     public string Replace()     {         return Content.Replace(' ', ',');     }      [Benchmark]     public string Join()     {         return string.Join(',', Content.Split(' '));     }      [Benchmark]     public string Base_Regex()     {         return Regex.Replace(Content, @\"\\s+\", \",\", RegexOptions.Compiled);     }      [GeneratedRegex(\"\\\\s+\")]     private static partial Regex GeneratedRegexReplace();      [Benchmark]     public string Generated_Regex()     {         return GeneratedRegexReplace().Replace(Content, \",\");     }      [Benchmark]     public string Char_NewString()     {         char[] chars = Content.ToCharArray();         for (int i = 0; i &lt; chars.Length; i++)         {             if (char.IsWhiteSpace(chars[i]))             {                 chars[i] = ',';             }         }          return new string(chars);     }      [Benchmark]     public string Char_NewString_FastFor()     {         char[] chars = Content.ToCharArray();         for (int i = 0, length = chars.Length; i &lt; length; i++)         {             if (char.IsWhiteSpace(chars[i]))             {                 chars[i] = ',';             }         }          return new string(chars);     }      [Benchmark]     public string Span_NewString()     {         Span&lt;char&gt; chars = new Span&lt;char&gt;(Content.ToCharArray());         for (int i = 0; i &lt; chars.Length; i++)         {             if (char.IsWhiteSpace(chars[i]))             {                 chars[i] = ',';             }         }          return new string(chars);     }      [Benchmark]     public string Span_Concat()     {         Span&lt;char&gt; chars = new Span&lt;char&gt;(Content.ToCharArray());         for (int i = 0; i &lt; chars.Length; i++)         {             if (char.IsWhiteSpace(chars[i]))             {                 chars[i] = ',';             }         }          return string.Concat(chars.ToArray());     }      [Benchmark]     public string Char_Concat()     {         char[] chars = Content.ToCharArray();         for (int i = 0; i &lt; chars.Length; i++)         {             if (char.IsWhiteSpace(chars[i]))             {                 chars[i] = ',';             }         }          return string.Concat(chars);     }      [Benchmark]     public string Unsafe_ReadOnlySpan_NewString()     {         ReadOnlySpan&lt;char&gt; chars = Content.AsSpan();         for (int i = 0; i &lt; chars.Length; i++)         {             if (!char.IsWhiteSpace(chars[i]))             {                 continue;             }              unsafe             {                 fixed (char* baseChar = chars)                 {                     char* newChar = baseChar + i;                     *newChar = ',';                 }             }         }          return new string(chars);     }      [Benchmark]     public string Unsafe_ReadOnlySpan_NewString_Foreach()     {         int i = 0;          ReadOnlySpan&lt;char&gt; chars = Content.AsSpan();         foreach (char @char in chars)         {             ++i;             if (!char.IsWhiteSpace(@char))             {                 continue;             }              unsafe             {                 fixed (char* baseChar = chars)                 {                     char* newChar = baseChar + i;                     *newChar = ',';                 }             }         }          return new string(chars);     }      [Benchmark]     public string Unsafe_String()     {         for (int i = 0; i &lt; Content.Length; i++)         {             if (!char.IsWhiteSpace(Content[i]))             {                 continue;             }              unsafe             {                 fixed (char* baseChar = Content)                 {                     char* newChar = baseChar + i;                     *newChar = ',';                 }             }         }          return Content;     }      [Benchmark]     public string Unsafe_String_Foreach()     {         int i = 0;         foreach (char @char in Content)         {             ++i;             if (!char.IsWhiteSpace(@char))             {                 continue;             }              unsafe             {                 fixed (char* baseChar = Content)                 {                     char* newChar = baseChar + i;                     *newChar = ',';                 }             }         }          return Content;     }      [Benchmark]     public string Marshal_Span_ToString()     {         Span&lt;char&gt; chars = MemoryMarshal.CreateSpan(ref MemoryMarshal.GetReference(Content.AsSpan()), Content.Length);         for (int i = 0; i &lt; chars.Length; i++)         {             if (char.IsWhiteSpace(chars[i]))             {                 chars[i] = ',';             }         }          return chars.ToString();     }      [Benchmark]     public string Marshal_Span_NewString()     {         Span&lt;char&gt; chars = MemoryMarshal.CreateSpan(ref MemoryMarshal.GetReference(Content.AsSpan()), Content.Length);         for (int i = 0; i &lt; chars.Length; i++)         {             if (char.IsWhiteSpace(chars[i]))             {                 chars[i] = ',';             }         }          return new string(chars);     }      [Benchmark]     public string String_Create()     {         string result = string.Create(Content.Length, Content, (chars, buffer) =&gt;         {             for (int i = 0; i &lt; chars.Length; i++)             {                 chars[i] = buffer[i];                 if (char.IsWhiteSpace(chars[i]))                 {                     chars[i] = ',';                 }             }         });                  return result;     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u0430\u043c\u043e\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0435, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b:<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u041a\u0430\u043a \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0432\u043f\u043e\u043b\u043d\u0435 \u0443\u0434\u0430\u0447\u0435\u043d, \u043d\u043e \u043d\u0435 \u0432\u043e \u0432\u0441\u0435\u0445 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044f\u0445, \u0442\u0430\u043a \u043a\u0430\u043a \u043f\u0430\u043c\u044f\u0442\u044c \u0432\u0441\u0435 \u0436\u0435 \u0440\u0430\u0441\u0445\u043e\u0434\u0443\u0435\u0442, \u0430 \u0432\u043e\u0442 unsafe \u043d\u0435\u0442, \u0447\u0442\u043e \u0432 \u0446\u0435\u043b\u043e\u043c \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e, \u043d\u043e \u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043a\u0440\u0430\u0439\u043d\u0435 \u0445\u0440\u043e\u043c\u0430\u0435\u0442.<\/p>\n<p>\u0421\u0442\u043e\u0438\u0442 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 for \u0438 \u0431\u043e\u043b\u0435\u0435 \u00ab\u043d\u043e\u0432\u0443\u044e\u00bb \u0432\u0435\u0440\u0441\u0438\u044e, \u0447\u0442\u043e \u043f\u043e \u0444\u0430\u043a\u0442\u0443 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0441\u0430\u0445\u0430\u0440, \u043d\u043e \u0432\u0441\u0435 \u0436\u0435 \u0440\u0430\u0437\u043d\u0438\u0446\u0430 \u0432 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0435\u0441\u0442\u044c.<\/p>\n<p>\u041a\u0430\u043a \u0438 \u0431\u044b\u043b\u043e \u0432\u043e \u0432\u0441\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0430, Regex \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0443\u0434\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u043e \u0441\u0442\u0440\u043e\u043a\u0430\u043c\u0438 \u0432 \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u043c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0435, \u0445\u043e\u0442\u044c \u0432\u043f\u043e\u043b\u043d\u0435 \u043a\u0440\u0430\u0441\u0438\u0432 \u043d\u0430 \u0432\u0438\u0434. \u041b\u0438\u0447\u043d\u043e \u0434\u043b\u044f \u043c\u0435\u043d\u044f \u0438\u043d\u0442\u0440\u0438\u0433\u0430 \u0431\u044b\u043b\u0430 \u0432 foreach \u0438 \u0432\u0441\u0435 \u0436\u0435 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 for \u0434\u043e \u0441\u0438\u0445 \u043f\u043e\u0440 \u0443\u0434\u0430\u0447\u043d\u044b\u0439 \u0432\u044b\u0431\u043e\u0440, \u0447\u0442\u043e \u0431\u044b \u0442\u0430\u043a \u043d\u0438 \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u0438 \u043f\u0440\u043e \u00ab\u044d\u0442\u043e \u0443\u0436\u0435 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043e\u00bb.<\/p>\n<p>\u0412<\/p>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-347696","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/347696","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=347696"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/347696\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=347696"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=347696"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=347696"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}