C#字符串查找的优化

这两天改变了关键词库,要求将以前的旧资料包括新闻问答商机等的所有数据的关键词重新匹配生成一遍。

先让老喻做了个功能页出来,生成12条数据大概要30、40秒左右,感觉太慢了,就自己再想想有没有更优的方法。

基本情况是:

总数据大概有300多万,分布在10来个表里。

关键词库约有4万。

 

关键词库已经存在Cache里了,对性能没什么影响。

 

  1.         public string[] KeyWordStrs = null;
  2.         /// <summary>
  3.         /// 获取缓存中的关键词组
  4.         /// </summary>
  5.         private void GetKeyWordStrs()
  6.         {
  7.             if (KeyWordStrs != null) { return; }
  8.             if (HttpContext.Current.Cache["keywords"] == null)
  9.             {
  10.                 string sql = "Select [Name] From [KeyWords]";
  11.                 DataSet dSet1 = GetDataSet(sql);
  12.                 if (dSet1 == null || dSet1.Tables.Count <= 0) { return; }
  13.                 string[] str = new string[dSet1.Tables[0].Rows.Count];
  14.                 for (int i = 0; i < dSet1.Tables[0].Rows.Count; i++)
  15.                 {
  16.                     str[i] = dSet1.Tables[0].Rows[i][0].ToString();
  17.                 }
  18.                 dSet1.Dispose();
  19.                 dSet1 = null;
  20.                 HttpContext.Current.Cache.Insert("keywords",str);
  21.                 return;
  22.             }
  23.             KeyWordStrs = (string[])HttpContext.Current.Cache["keywords"];
  24.         }

反复测试,发现最浪费时间的就是每次的4万次匹配。

一开始是用IndexOf方法来验证,从数据表里将记录读出来,每次1000条左右,循环中再从4万个词库里判断是否大于0,组合成关键词组:

  1.     /// <summary>
  2.     /// 返回关键词字符串,不超过100个字符
  3.     /// </summary>
  4.     /// <param name="title">标题</param>
  5.     /// <param name="content">内容</param>
  6.     /// <returns>返回关键词字符串</returns>
  7.     public string GetKeyWords(string title, string content)
  8.     {
  9.         GetKeyWordStrs();
  10.         if (KeyWordStrs == null) { return ""; }
  11.         if (content.Length < 2 && title.Length < 2) { return ""; }
  12.         string keywords = string.Empty;
  13.         //如果标题长度小于2,只匹配内容
  14.         if (title.Length < 2)
  15.         {
  16.             foreach (string s in KeyWordStrs)
  17.             {
  18.                 if (content.IndexOf(s) >= 0)
  19.                 {
  20.                     keywords = keywords + "," + s;
  21.                 }
  22.                 //如果长度大于99则中止循环
  23.                 if (keywords.Length > 99) { break; }
  24.             }
  25.         }
  26.         else
  27.         {
  28.             foreach (string s in KeyWordStrs)
  29.             {
  30.                 //如果标题已经匹配
  31.                 if (title.IndexOf(s)>= 0)
  32.                 {
  33.                     keywords = keywords + "," + s;
  34.                 }
  35.                 //标题未能匹配时再按内容匹配
  36.                 else if (content.IndexOf(s)>= 0)
  37.                 {
  38.                     keywords = keywords + "," + s;
  39.                 }
  40.                 //如果长度大于99则中止循环
  41.                 if (keywords.Length > 99) { break; }
  42.             }
  43.         }
  44.     }

随机取了1 2条数据,总费时34-40秒左右。

这种效果肯定不行,于是自己找了找字符串查找的相关优化方法,GOOGLE和BAIDU也没提到什么,想了一下用正则的试试看看,改了一下代码:

  1.     /// <summary>
  2.     /// 返回关键词字符串,不超过100个字符
  3.     /// </summary>
  4.     /// <param name="title">标题</param>
  5.     /// <param name="content">内容</param>
  6.     /// <returns>返回关键词字符串</returns>
  7.     public string GetKeyWords(string title, string content)
  8.     {
  9.         GetKeyWordStrs();
  10.         if (KeyWordStrs == null) { return ""; }
  11.         if (content.Length < 2 && title.Length < 2) { return ""; }
  12.         string keywords = string.Empty;
  13.         Regex r;
  14.         //如果标题长度小于2,只匹配内容
  15.         if (title.Length < 2)
  16.         {
  17.             foreach (string s in KeyWordStrs)
  18.             {
  19.                 //先过滤特殊字符
  20.                 r = new Regex(s.Replace(".", @"/.").Replace("(""").Replace(")"""));
  21.                 if (r.IsMatch(content))
  22.                 {
  23.                     keywords = keywords + "," + s;
  24.                 }
  25.                 //如果长度大于99则中止循环
  26.                 if (keywords.Length > 99) { break; }
  27.             }
  28.         }
  29.         else
  30.         {            
  31.             foreach (string s in KeyWordStrs)
  32.             {
  33.                 //先过滤特殊字符
  34.                 r = new Regex(s.Replace(".", @"/.").Replace("(""").Replace(")"""));
  35.                 //如果标题已经匹配
  36.                 if (r.IsMatch(title))
  37.                 {
  38.                     keywords = keywords + "," + s;
  39.                 }
  40.                 //标题未能匹配时再按内容匹配
  41.                 else if (r.IsMatch(content))
  42.                 {
  43.                     keywords = keywords + "," + s;
  44.                 }
  45.                 //如果长度大于99则中止循环
  46.                 if (keywords.Length > 99) { break; }
  47.             }
  48.         }
  49.     }

有提高了,同样的12条数据花了12秒左右,有了明显的提升呢。

不知道还有没更快的方式呢?

乱找了一下,发现String有个Contains方法,试了一下,时间一下子就缩短到4左右,看来这个效率是最快的了。

  1.     public string GetKeyWords(string title, string content)
  2.     {
  3.         GetKeyWordStrs();
  4.         if (KeyWordStrs == null) { return ""; }
  5.         if (content.Length < 2 && title.Length < 2) { return ""; }
  6.         //如果标题长度小于2,只匹配内容
  7.         if (title.Length < 2)
  8.         {
  9.             foreach (string s in KeyWordStrs)
  10.             {
  11.                 //如果标题已经匹配
  12.                 if (title.Contains(s))
  13.                 {
  14.                     keywords = keywords + "," + s;
  15.                 }
  16.                 //标题未能匹配时再按内容匹配
  17.                 else if (content.Contains(s))
  18.                 {
  19.                     keywords = keywords + "," + s;
  20.                 }
  21.                 //如果长度大于99则中止循环
  22.                 if (keywords.Length > 99) { break; }
  23.             }
  24.         }
  25.         else
  26.         {            
  27.             foreach (string s in KeyWordStrs)
  28.             {
  29.                 //如果标题已经匹配
  30.                 if (title.Contains(s))
  31.                 {
  32.                     keywords = keywords + "," + s;
  33.                 }
  34.                 //标题未能匹配时再按内容匹配
  35.                 else if (content.Contains(s))
  36.                 {
  37.                     keywords = keywords + "," + s;
  38.                 }
  39.                 //如果长度大于99则中止循环
  40.                 if (keywords.Length > 99) { break; }
  41.             }
  42.         }
  43.     }

 

不知道还没有更好的方式来处理呢?

关于本软件——SEO排名检索工具——突破传统排名查询概念——超越观其排名查询工具 =========================================================================================== 打造中国站长自己的软件:SEO排名检索工具 SEO排名检索工具 | SEO排名检索工具 (0 0) +-----oOO----(_)----------+ | 掌控自己 | | 把握敌人 | | 德玛西亚万岁 | +------------------oOO----+ |__|__| || || ooO Ooo ==================================== 软件操作说明 ======================================== =========================================================================================== |★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆O_|_O☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★| =========================================================================================== 1.搜索关键词:搜索关键词数量不限,每行一个关键词。 2.索引关键词:索引关键词数量不限,每行一个关键词。索引关键词是指作为唯一判断词,如图demo.jpg。 注意:尽可能使用公司名称或简称作为索引关键词,切勿将搜索关键词作为索引关键词,否则可能出现查 询结果误差。因为百度搜索结果中关键词一般都为标红状态,如果将搜索关键词作为索引关键词,可能出 现索引关键词不完整检索,导致查询结果误差。一般发布信息都会加上本公司名称,即唯一检索标准。 正确的搜索如:搜索关键词为“羽绒服”;索引关键词为“波士顿”。“羽绒服”搜索关键词; “波士顿”为品牌名称或公司名。 3.网站域名:网站域名数量不限,每行一个关键词。辅助查询结果用,可不填写,如填写可增加查询结果 的准确性。 注意:只需要填写网站主域名即可。 4.排名页面:根据以上条件进行查询,获取百度搜索结果前N位所出现的所有排名页面结果。 作用:方便了解自身产品在百度首页占据数量及相关页面,对结果可以做出及时的优化调整。 5.榜上有名:用于查询百度首页或前N页中每个“索引关键词”出现的位置排名及网站域名。 作用:用来分析本公司与竞争对手的排名优劣势,以及信息来源。 6.下拉框:10、20、50、100表示查询前多少位中的数据,10即前10以内;100即前100以内; ==================================== 软件操作说明 ======================================== =========================================================================================== |★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆O_|_O☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★| =========================================================================================== ==================================== 使 用 协 议 ======================================== 1.本程序来源于互联网,版权归程序原作者所有。软件最终解释权归程序原作者所有。 2.本软件上传前经过最新360查杀,但也可能有别的原因查毒不彻底,敬请下载后自行重新检查,谢谢合作。 3.由于程序来源于互联网,所以不能完全保证程序安全性,如出现任何经济或商业机密损失概不负责。 4.本程序只供研究使用,请在下载后24小时内删除!使用本软件所产生的【任何】损失都由使用者本人负责。 ==================================== 使 用 协 议 ======================================== ==================================== 2012年11月23日========================================    /\~~~~~~~~~~~~~\   ▓  ^*^   ☆  $$  .☆   ./ \~~~▓~  ~~~~\ ◆  圣诞 .快乐  *  $◢◣$  *   / ^^ \ ══════\.◆    * *  *  $◢★◣$  *  ..▎[] ▎田 田 ▎ |┃◆  .     *  $◢■■◣$  *  &&▎  ▎    ▎'|'▎ @       * $◢■■■◣$ * # ■■■■■■■■■■〓▄▃▂▁愿你圣诞快乐︸︸||︸︸
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值