zoukankan      html  css  js  c++  java
  • 字符串的耗时操作

    在一个新闻采集的项目中,处理一条信息时CPU竟然耗尽,后查找原因发现在一个do...while循环里耗时竟超过20分钟。一般而言,一百万的循环耗时一般为一秒。因此如果一个循环就能将CPU耗尽长达20多分钟,那么循环里一定会有其它非循环操作在作怪。原处理方法如下:

    /// <summary>
            /// 格式化Html正文.
            /// </summary>
            /// <param name="Content">Html文档内容。</param>
            /// <param name="Buf">结果缓冲区。</param>
            public static void FormatHtml(string Content, HtmlBufBase Buf)
            {
                if (string.IsNullOrEmpty(Content))
                    return;
                // 过滤前面未处理的标记
                int TagEnd = Content.IndexOf('>', 0);
                if (TagEnd == -1)
                    TagEnd = 0;
                else
                {
                    //处理Title中的HTML标签
                    int pos = GetNextTagStartPosition(Content, 0);
                    if (pos > -1 && TagEnd > pos)
                        TagEnd = 0;
                    else
                        TagEnd++;
                }
                bool bIsNotInHideTag = true;  // 是否不在隐藏的标记内容中
                bool bIsNotInStyle = true;
                string HideTag = null;
                string LastTag = null;
                do
                {
                    if (Content.Contains("国家统计局服务业调查中心"))
                    {
                    }
                    // 找标记开始
                    int TagStart = GetNextTagStartPosition(Content, TagEnd);
                    if (TagStart == -1)
                        TagStart = Content.Length;// 达到结尾
                    else if (Content.IndexOf("!--", TagStart) == TagStart+1)   // 判断是否是注释
                    {
                        TagEnd = Content.IndexOf("-->", TagStart)+3;
                        if (TagStart == -1)
                            TagStart = Content.Length;
                        continue;
                    }
                    // 转换内容
                    if (bIsNotInHideTag && bIsNotInStyle)
                        Buf.AppendText(Content.Substring(TagEnd, TagStart - TagEnd));
                    // 找标记结束
                    TagEnd = GetNextTagEndPosition(Content, TagStart);
                    if (TagEnd > -1)
                    {
                        TagEnd++;
                        TagStart++;
                        string TagInfo;
                        string Tag = GetTagAndTagInfo(Content, TagEnd, TagStart, out TagInfo);
     
                        if (Tag == "script")  // 脚本开始
                        {
                            int scriptEndPos = Content.IndexOf("</script>", TagStart, StringComparison.OrdinalIgnoreCase);
                            if (scriptEndPos > 0)
                            {
                                TagEnd = scriptEndPos + 9;
                            }
                            else
                            {
                                TagEnd = Content.Length;
                            }
                        }
                        else if (Tag == "style")
                        {
                            bIsNotInStyle = false;
                        }
                        else if (Tag == "/style")
                        {
                            bIsNotInStyle = true;
                        }
                        else if (TagInfo.ToLower().IndexOf("display:none") > 0)
                        {
                            bIsNotInHideTag = false;
                            HideTag = Tag;
                        }
                        else if (Tag == "/" + HideTag)
                        {
                            bIsNotInHideTag = true;
                            HideTag = null;
                        }
                        else
                            Buf.AppendTag(Tag, TagInfo);
     
                        //else if (Tag == "base")
                        //    BaseUrl = GetBaseUrl(TagInfo);
                        LastTag = Tag;
                    }
                    else
                        break;
                } while (true);
                Buf.ReFormatText();
            }
     
    最近查找到有一条语句特别耗时即
     else if (Content.IndexOf("!--", TagStart) == TagStart+1)   // 判断是否是注释,这个字符串的查找都是全文查找,肯定特别耗时,这条语句的功能是判断标签是否是注释,因此没必要去判断”!--“只需要判断!即可。因此使用字符查找即可,改动如下:
     else if (Content[TagStart+1] == '!')   // 判断是否是注释
    改成上面语句后CPU尽管会耗尽,但耗时只需30秒。
    深入追究一下,可知字符的查找应该是数组的查找,为什么不直接使用数组下标呢?改动如下:
    Content[TagStart + 1] == '!'
    改后测试一下,在本方法中的两万多次循环中只需要60毫秒。
    最后程序改动如下:
     /// <summary>
            /// 格式化Html正文.
            /// </summary>
            /// <param name="Content">Html文档内容。</param>
            /// <param name="Buf">结果缓冲区。</param>
            public static void FormatHtml(string Content, HtmlBufBase Buf)
            {
                if (string.IsNullOrEmpty(Content))
                    return;
     
                // 过滤前面未处理的标记
                int TagEnd = Content.IndexOf('>', 0);
                if (TagEnd == -1)
                    TagEnd = 0;
                else
                {
                    //处理Title中的HTML标签
                    int pos = GetNextTagStartPosition(Content, 0);
                    if (pos > -1 && TagEnd > pos)
                        TagEnd = 0;
                    else
                        TagEnd++;
                }
                bool bIsNotInHideTag = true;  // 是否不在隐藏的标记内容中
                bool bIsNotInStyle = true;
     
                string HideTag = null;
                string LastTag = null;
                do
                {
                    // 找标记开始
                    int TagStart = GetNextTagStartPosition(Content, TagEnd);
                    if (TagStart == -1)
                        TagStart = Content.Length;// 达到结尾
                  
                    // 转换内容
                    if (bIsNotInHideTag && bIsNotInStyle)
                        Buf.AppendText(Content.Substring(TagEnd, TagStart - TagEnd));
                    // 判断是否是注释
                    if (TagStart != -1 && TagStart < Content.Length && Content[TagStart + 1] == '!')   
                    {
                        TagEnd = Content.IndexOf("-->", TagStart);
                        if (TagEnd == -1)//没有找到注释的结束标记
                        {
                            TagEnd = Content.Length;
                        }
                        else//有注释的结束标记,跳过本标记
                        {
                            TagEnd = TagEnd + 3;
                            continue;
                        }
                    }
                    // 找标记结束
                    TagEnd = GetNextTagEndPosition(Content, TagStart);
                    if (TagEnd > -1)
                    {
                        TagEnd++;
                        TagStart++;
                        string TagInfo;
                        string Tag = GetTagAndTagInfo(Content, TagEnd, TagStart, out TagInfo);
     
                        if (Tag == "script")  // 脚本开始
                        {
                            int scriptEndPos = Content.IndexOf("</script>", TagStart, StringComparison.OrdinalIgnoreCase);
                            if (scriptEndPos > 0)
                            {
                                TagEnd = scriptEndPos + 9;
                            }
                            else
                            {
                                TagEnd = Content.Length;
                            }
                        }
                        else if (Tag == "style")
                        {
                            bIsNotInStyle = false;
                        }
                        else if (Tag == "/style")
                        {
                            bIsNotInStyle = true;
                        }
                        else if (TagInfo.ToLower().IndexOf("display:none") > 0)
                        {
                            bIsNotInHideTag = false;
                            HideTag = Tag;
                        }
                        else if (Tag == "/" + HideTag)
                        {
                            bIsNotInHideTag = true;
                            HideTag = null;
                        }
                        else
                            Buf.AppendTag(Tag, TagInfo);
     
                        //else if (Tag == "base")
                        //    BaseUrl = GetBaseUrl(TagInfo);
                        LastTag = Tag;
                    }
                    else
                        break;
                } while (true);
                Buf.ReFormatText();
            }
  • 相关阅读:
    spring Di依赖注入
    Spring cloud微服务安全实战-6-7jwt改造总结
    Spring cloud微服务安全实战-6-6jwt改造之日志及错误处理(2)
    Spring cloud微服务安全实战-6-5jwt改造之日志及错误处理(1)
    Spring cloud微服务安全实战-6-4权限控制改造
    Spring cloud微服务安全实战-6-3JWT改造之网关和服务改造
    Spring cloud微服务安全实战-6-2JWT认证之认证服务改造
    Spring cloud微服务安全实战-6-1本章概述
    Spring cloud微服务安全实战-5-12实现基于token的SSO(2)
    Spring cloud微服务安全实战-5-11实现基于token的SSO(1)
  • 原文地址:https://www.cnblogs.com/chensuqian/p/9644813.html
Copyright © 2011-2022 走看看