50分求解一效率优化问题
用数据库方式实现文档的倒排索引,数据库有3张表,表一:文档表,字段有url,文档id,文档内容,标题等,表二:单词表,字段有单词id,单词和单词出现频率,表三:文档单词关系表,字段有文档id,单词id,和单词在文档出现的位置号.
我现在的做法是这样的,首先把数据填入表二
while(从表一读取文档内容)
{ split文档内容,得到单词的字符串数组
for(循环数组,对每一个单词)
{
1。对每个单词还作了些字符串处理并舍弃一些不要的单词
2。先判断单词是否已经在表二中出现过,没有则3,有的话词频加一
3。插入表二
}
}
做完表二后再做表三。基本和上面差不多,只是在循环数组的时候要取出该单词在表二的id。
这样一个结构效率很低下,不知有什么办法可以提高效率,请高手指点,谢谢
------解决方案--------------------基本的算法可能也就这样,个人觉得实现上可以作一点改进
1、程序开始的时候把表二中的所有单词的信息读进来,放到HashTable(.net 1.1)或是Dictionary <key,word> 里面(.net 2.0 wrod是程序定义的单词结构);同时定义另一个Dictionary <key,word> 的容器,用于存放表二里没有的单词信息
2、程序处理的时候,只是要字典里去查,省去数据库查找过程(对大数据量的处理节省很多时间)。前面不用ArrayList或是List <word> 是因为查找性能上HashTable更优
3、当然咯,程序处理完了,把这些信息update或是insert到表二就OK了
楼主如果对容器不是很熟悉的话,看一下交资料很快就明白了
------解决方案--------------------建议:
1、减少数据库读取次数。一次性读取所有需要的数据,怎么读取? 可以构造 sql,存放在DataTable 或则其他什么地方;
2、suxe() 提到的使用字典加速。
看你的思路中,看第一句就感觉问题比较大。如果你这句:while(从表一读取文档内容)。有数据库操作(读取数据,即使只读取一条数据)是比较耗时的,像提高,可以按照suxe()意见,见数据一次性读取出来放在字典中,然后再字典中查找数据,速度会快很多。
------解决方案--------------------我写了一个大概,完整了代码就可以了
public struct Word
{
public int Id;
public string Characters;
public int Frequency;
public static bool operator ==(Word x, Word y)
{
return x.Characters == y.Characters;
}
}
public class WordManager
{
//初始容器
private WordManager()
{// 。。。}
public static WordManager Instance
{
get
{
if (__instance != null)
{
return __instance;
}
__instance = new WordManager();
return __instance;
}
}
//从数据库把单词信息加载到m_primaryWords
public void Load()
{ //。。。}
//更新单词信息,如果单词在m_primaryWords中,则frequency++,否则新加单词到m_newWords
public void Update(ref Word item)
{
if (m_primaryWords.ContainsKey(item.Characters))
{
m_primaryWords[item.Characters].Frequency++;
}
else
{
m_newWords.Add(item.Characters, item);
}
}
//把m_primaryWords和m_newWords容器中的单词信息保存到数据库
public void Save()
{
foreach (Word item in m_primaryWords)
{
//update进表或者可以先把表清空了再插入
}
foreach (Word item in m_newWords)
{
//insert 进表
}
}
private Dictionary <string, Word> m_primaryWords;
private Dictionary <string, Word> m_newWords;
private static WordManager __instance;
}