"不要在这个热代码路径中使用StringBuilder或foreach"

Lar*_*rry 32 .net optimization foreach stringbuilder signalr

我正在浏览开源SignalR项目的源代码,我看到这个名为"不要在这个热代码路径中使用StringBuilder或foreach"的差异代码:

-           public static string MakeCursor(IEnumerable<Cursor> cursors)
+           public static string MakeCursor(IList<Cursor> cursors)
            { 
-               var sb = new StringBuilder();
-               bool first = true;
-               foreach (var c in cursors)
+               var result = "";
+               for (int i = 0; i < cursors.Count; i++)
                {
-                   if (!first)
+                   if (i > 0)
                    {
-                       sb.Append('|');
+                       result += '|';
                    }
-                   sb.Append(Escape(c.Key));
-                   sb.Append(',');
-                   sb.Append(c.Id);
-                   first = false;
+                   result += Escape(cursors[i].Key);
+                   result += ',';
+                   result += cursors[i].Id;
                }
-               return sb.ToString();
+               return result;
            }
Run Code Online (Sandbox Code Playgroud)

我理解为什么foreach有时效率会降低,为什么它会被for取代.

但是,我学习并体验到StringBuilder是连接字符串的最有效方法.所以我想知道为什么作者决定用标准连接替换它.

使用StringBuilder在这里和一般情况下有什么问题?

dav*_*owl 30

我做了代码更改,是的,它在分配数量(GetEnumerator())调用方面产生了巨大差异.想象一下,这段代码每秒数百万次.分配的调查员数量是荒谬的,可以避免.

编辑:我们现在反转控制以避免任何分配(直接写入编写器):https: //github.com/SignalR/SignalR/blob/2.0.2/src/Microsoft.AspNet.SignalR.Core/Messaging/ Cursor.cs#L36