三国卡牌客户端基础资源仓库
hch
8 天以前 fcce9ab0e54e4580569ba4ed5be0f4e3ba4d37fa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
using UnityEngine;
using System.Collections;
using System.Text;
using System;
using System.Collections.Concurrent;
 
 
// AI提醒实际在现代编辑器中,低于4个字符串的+ 操作符的性能和 string.Concat 几乎相同,会被智能优化为 string.Concat
public class StringUtility
{
    public static readonly string[] splitSeparator = new string[] { "|" };
 
    // 对象池方案:线程安全的StringBuilder池
    private static readonly ConcurrentQueue<StringBuilder> _stringBuilderPool = new ConcurrentQueue<StringBuilder>();
    private const int MAX_POOL_SIZE = 32;  // 增加池大小以适应高并发
    private const int DEFAULT_CAPACITY = 64;
    private const int SMALL_CAPACITY = 64;   // 适用于小规模拼接
    private const int TINY_CAPACITY = 32;    // 适用于极小规模拼接
    private const int MEDIUM_CAPACITY = 128; // 新增中等容量级别
    private const int LARGE_CAPACITY = 256;  // 新增大容量级别
 
 
    /// <summary>
    /// 智能容量估算(优化版)
    /// </summary>
    private static int EstimateCapacity(params string[] objects)
    {
        if (objects == null || objects.Length == 0)
            return TINY_CAPACITY;
 
        int totalLength = 0;
 
        // 单次遍历计算总长度,提高性能
        foreach (string str in objects)
        {
            if (str != null)
                totalLength += str.Length;
        }
 
        // 更精细的容量策略,减少内存浪费
        if (totalLength <= TINY_CAPACITY)
            return TINY_CAPACITY;
        else if (totalLength <= SMALL_CAPACITY)
            return SMALL_CAPACITY;
        else if (totalLength <= MEDIUM_CAPACITY)
            return MEDIUM_CAPACITY;
        else if (totalLength <= LARGE_CAPACITY)
            return LARGE_CAPACITY;
        else
            // 对于超大字符串,预留25%的缓冲空间(减少内存浪费)
            return totalLength + (totalLength >> 2);
    }
 
    /// <summary>
    /// 从对象池获取StringBuilder
    /// </summary>
    private static StringBuilder GetPooledStringBuilder(int capacity = DEFAULT_CAPACITY)
    {
        if (_stringBuilderPool.TryDequeue(out StringBuilder sb))
        {
            sb.Clear();
            // 如果容量不足,重新创建
            if (sb.Capacity < capacity)
            {
                sb = new StringBuilder(capacity);
            }
            return sb;
        }
        return new StringBuilder(capacity);
    }
 
    /// <summary>
    /// 将StringBuilder归还到对象池(优化版)
    /// </summary>
    private static void ReturnToPool(StringBuilder sb)
    {
        if (sb == null)
            return;
 
        // 容量过大或过长,不回收以避免内存问题
        if (sb.Capacity > 2048 || sb.Length > 1024)
        {
            SecureClear(sb);
            return;
        }
 
        // 池未满时才回收
        if (_stringBuilderPool.Count < MAX_POOL_SIZE)
        {
            sb.Clear();
            _stringBuilderPool.Enqueue(sb);
        }
        else
        {
            // 池满时进行安全清理
            SecureClear(sb);
        }
    }
 
    /// <summary>
    /// 安全清理StringBuilder内容(防止敏感数据泄露)
    /// </summary>
    private static void SecureClear(StringBuilder sb)
    {
        if (sb == null || sb.Length == 0)
            return;
 
        // 基础清理
        sb.Clear();
 
        // 安全清理:用空字符覆盖缓冲区
        // #if UNITY_EDITOR || DEVELOPMENT_BUILD
        // // 仅在开发版本中执行更彻底的清理,避免影响性能
        // int originalCapacity = sb.Capacity;
        // if (originalCapacity <= 1024) // 仅对小容量StringBuilder进行安全清理
        // {
        //     sb.Capacity = originalCapacity;
        //     for (int i = 0; i < originalCapacity; i++)
        //     {
        //         sb.Append('\0');
        //     }
        //     sb.Clear();
        // }
        // #endif
    }
 
    /// <summary>
    /// 智能字符串拼接方法(优化版),自动选择最优策略
    /// - 1-4个字符串:直接使用 string.Concat() (最高性能)
    /// - 4-8个字符串:使用对象池 StringBuilder,容量预分配
    /// - 9个以上字符串:使用对象池 StringBuilder + 容量估算
    /// </summary>
    public static string Concat(params string[] _objects)
    {
        if (_objects == null || _objects.Length == 0)
            return string.Empty;
 
        // 少量字符串直接使用Concat,性能最佳
        if (_objects.Length <= 4)
        {
            return string.Concat(_objects);
        }
 
        // 中等数量字符串使用简单容量策略
        int estimatedCapacity;
        if (_objects.Length <= 8)
        {
            estimatedCapacity = DEFAULT_CAPACITY;
        }
        else
        {
            // 大量字符串才进行容量估算(优化性能)
            estimatedCapacity = EstimateCapacity(_objects);
        }
 
        var sb = GetPooledStringBuilder(estimatedCapacity);
        try
        {
            foreach (string str in _objects)
            {
                sb.Append(str);
            }
            return sb.ToString();
        }
        finally
        {
            ReturnToPool(sb);
        }
    }
 
 
    public static string FormatSpeed(float speed)
    {
        if (speed > 1048576f)
        {
            return Concat((speed / 1048576f).ToString("f1"), " M/S");
        }
        else if (speed > 1024f)
        {
            return Concat((speed / 1024f).ToString("f1"), " KB/S");
        }
        else
        {
            return Concat(speed.ToString("f1"), " B/S");
        }
    }
 
    /// <summary>
    /// 预热对象池(在应用启动时调用)
    /// </summary>
    public static void WarmupPool(int count = 4)
    {
        // 预热不同容量的StringBuilder以适应不同场景
        for (int i = 0; i < count && _stringBuilderPool.Count < MAX_POOL_SIZE; i++)
        {
            _stringBuilderPool.Enqueue(new StringBuilder(DEFAULT_CAPACITY));
        }
    }
 
 
 
}