zoukankan      html  css  js  c++  java
  • c#中string拼接的效率分析

    通过unity profiler测试的代码,及运行结果

    using UnityEngine;
    using UnityEngine.Profiling;
    using System.Text;
    
    #if UNITY_5_5_OR_NEWER
    using TProfiler = UnityEngine.Profiling.Profiler;
    #else
    using TProfiler = UnityEngine.Profiler;
    #endif
    
    public namespace Test {
    
        /// string concat test
        public class TestString : MonoBehaviour {
            // Update is called once per frame
            void Update ()
            {
                // loop 10000times
                for(int i = 0; i < 10000; ++i) {
    
                    TestString();
                }
    
                TestString10000();
            }
    
            // object new once
            private StringBuilder _sb = new StringBuilder();
    
            /// concat 10000 times
            private void TestString10000() {
    
                // +
                TProfiler.BeginSample("string.(10000+)");
                string s1 = string.Empty;
                for(int i = 0; i < 10000; ++i) {
                    s1 = s1 + ((int)Time.time).ToString();
                }
                TProfiler.EndSample();
    
    
                // StringBuilder Append
                TProfiler.BeginSample("StringBuilder.10000Append");
                _sb.Clear();
                for(int i = 0; i < 10000; ++i) {
                    _sb.Append((int)Time.time);
                }
                string s2 = _sb.ToString();
                TProfiler.EndSample();
            }
    
            /// concat 3 parts
            private void TestString() {
    
                System.Random random = new System.Random();
    
                // +
                TProfiler.BeginSample("string.(+)");
                string s1 = "txt_pre_" + random.Next().ToString() + "_end";
                TProfiler.EndSample();
    
                // Concat
                TProfiler.BeginSample("string.Concat");
                string s2 = string.Concat("txt_pre_", random.Next(), "_end");
                TProfiler.EndSample();
    
                // Concat ToString()
                TProfiler.BeginSample("string.Concat & int.ToString");
                string s3 = string.Concat("txt_pre_", ((int)Time.time).ToString(), "_end");
                TProfiler.EndSample();
    
                // format
                TProfiler.BeginSample("string.Format");
                string s4 = string.Format("txt_pre_{0}_end", (int)Time.time);
                TProfiler.EndSample();
    
                // format ToString()
                TProfiler.BeginSample("string.Format & int.ToString");
                string s5 = string.Format("txt_pre_{0}_end", ((int)Time.time).ToString());
                TProfiler.EndSample();
    
                // StringBuilder AppendFormat
                TProfiler.BeginSample("StringBuilder.AppendFormat & int.ToString");
                _sb.Clear();
                _sb.AppendFormat("txt_pre_{0}_end", ((int)Time.time).ToString());
                string s6 = _sb.ToString();
                TProfiler.EndSample();
    
                // StringBuilder Append
                TProfiler.BeginSample("StringBuilder.Append");
                _sb.Clear();
                _sb.Append("txt_pre_");
                _sb.Append((int)Time.time);
                _sb.Append("_end");
                string s7 = _sb.ToString();
                TProfiler.EndSample();
    
                // StringBuilder Append ToString()
                TProfiler.BeginSample("StringBuilder.Append & int.ToString");
                _sb.Clear();
                _sb.Append("txt_pre_");
                _sb.Append(((int)Time.time).ToString());
                _sb.Append("_end");
                string s8 = _sb.ToString();
                TProfiler.EndSample();
    
                // StringBuilder AppendNumber
                TProfiler.BeginSample("StringBuilder.AppendNumber");
                _sb.Clear();
                _sb.Append("txt_pre_");
                _sb.AppendNumber((int)Time.time);
                _sb.Append("_end");
                string s9 = _sb.ToString();
                TProfiler.EndSample();
            }
        }
    }
    View Code

    运行结果: 

    结果分析及结论: 


    1、string.Format和StringBuider.AppendFormat()

    可读性好 
    堆内存开销高,因为Format需要额外的内存分配 
    运行效率低 
    建议: 
    【少用,慎用】 


    2、StringBuilder.Append

    可读性一般 
    堆内存开销低 
    运行效率较高 
    建议: 
    大量字符串拼接时【必须使用】,内存及运行效率优化效果十分明显 
    少量字符串拼接时【酌情使用】,如调用频度 


    3、+和Concat

    可读性较好 
    堆内存开销低 
    运行效率较高 
    在很多情况下,+会被优化为Concat 
    建议: 
    大量字符串拼接时【禁止使用】,内存及运行效率开销非常大,无法忍受 
    少量字符串拼接时【建议使用】 
    另外,对于string拼接时的int等基本数据类型,养成ToString()的习惯,避免Box操作带来的额外内存开销。

    一个通用的int(Enum)转string的缓存方案

    /// Sample for SimpleDictCache
        ///    private static SimpleDictCache<EnumType> nameCache;
        /// 指挥官头像icon
        //    public static string GetName(EnumType id)
        //    {
        //        if (nameCache == null)
        //            nameCache = new SimpleDictCache<EnumType>();
        //
        //        return nameCache.Get((int)id, id, (o) => {
        //            return o.ToString(); // 此处可以替换为复杂的获取string的实现
        //        });
        //    }
        /// 通用Dictionary<int, string>缓存
        /// 比如enum对应的string可以用cache方式避免反复ToString()操作
        class SimpleDictCache<T>
        {
            public delegate string CacheValue(T id);
        
            private Dictionary<int, string> data;
        
            public string Get(int k, T id, CacheValue cv)
            {
                if (data == null)
                    data = new Dictionary<int, string>();
        
                if (data.ContainsKey(k))
                {
                    return data[k];
                }
        
                if (cv != null)
                    data.Add(k, cv(id));
                else
                    data.Add(k, string.Empty);
        
                return data[k];
            }
        }

    作者:dongzee
    出处:http://www.cnblogs.com/dongzee
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接
    如有问题,可以通过  dongzee1984#gmail.com  联系我,非常感谢。

  • 相关阅读:
    脑洞大开的爬虫解决思路 转载:https://mp.weixin.qq.com/s/Bd-wz_RiRpYv8ufIbQTZDg
    js逆向某东滑块 转载 https://mp.weixin.qq.com/s/eZSTfduYS63-LOvkAofxqA
    不能爬小程序,叫什么会爬虫 【参考资料也要看】 https://mp.weixin.qq.com/s/oDG3k_qjMZaoygZmz9OUDw
    HDU6042 Journey with Knapsack
    HDU7073 Integers Have Friends 2.0
    CF1439C Greedy Shopping
    CF813E Army Creation
    POJ1322 Chocolate
    CF451E Devu and Flowers
    POJ3734 Blocks
  • 原文地址:https://www.cnblogs.com/dongzee/p/7406328.html
Copyright © 2011-2022 走看看