这是一段载入词库的代码 并将词库里的数据放入链表,但是效率极低,将432KB的 txt文本文档的内容载入并存入链表要近两分钟时间。 这里该怎么优化?//文档内容均为中文。
#include <iostream>
#include <fstream>//文件类的头文件
#include <afx.h>// MFC类的头文件
#include <stdio.h>
#include <afxwin.h> //框架窗口的头文件
#include <afxtempl.h>//CList类的头文件
#include <string>
using namespace std;int InitialLinkList(FILE * const file,CList<char *,char*> * const clist,int CharCount);//初始化链表CList<char *,char*> listTwo;int main()
{
string Sentence =""; FILE * fileOne = fopen("TwoChar1.txt","r");
if(InitialLinkList(fileOne,&listTwo,2*2+1) == -1)//2个汉字的词库中文占5个字节。
return -1;//如果返回-1表示词库一打开失败 ,主函数返回,链表初始化不成功。
return 0;
}int InitialLinkList(FILE * const file,CList<char *,char*> * const clist,int CharSum)
{
if(file == NULL)
return -1; while(!feof(file))
{
char * strbuf = new char[CharSum];//初始化指定的链表
memset(strbuf,0,CharSum);
fgets(strbuf,CharSum,file);//从文件中获取CharSum大小数据写入堆中
clist ->AddTail(strbuf);//将堆的指针压入链表
}
fclose(file);//关闭词库文件。
}

解决方案 »

  1.   

    “将词库里的数据放入链表”是指用户的常规操作--装载词库么?    while(!feof(file)    循环中,你到底想做什么,为什么这么写?
      

  2.   

    其实2楼说的那样,速度应该差不多,因为Windows是由缓存机制的,所以就算你不读到内存缓冲区,还是相当于在内存解析。
    主要是你的数据结构不对,词库存储的方式不对,不能用文本文件。应该用一条条struct写入的二进制的记录文件,而且是应该有索引或排序的。用结构的好处时限定每个元素的长度,这样读取时就可以直接memcpy而不需要逐个字符处理。
    读内存时直接转换为二叉查找树之类的,肯定效率高很多。
      

  3.   

    不见得吧,虽然windows有缓存机制,可是依赖于未文档化的缓存并不可靠建议试试一次读完,然后解析如果这样还觉得慢,那干脆直接用FileMapping吧
      

  4.   


    内存缓冲区是什么意思? 是一个变量吗? 因为我的词库是一行一个词语的。一行都是两个字的词语。 保存为TXT文档,大小大概是489KB我将这个文件中的词语一行一行的读取到链表中。 结果这段时间花了近2分钟。 FileMapping是什么?
      

  5.   

    个人估计时间是花在了fget上
    400多K,全读到内存不算问题,解析完记得及时释放掉就行FileMapping就是文件映射,允许你像使用指针一样去操作硬盘上的文件
      

  6.   

    因为C语言的标准读取方式必须要转换行符等,就算你不fgets,照样还是有一个逐个字符处理的过程,这个绝对拖慢速度。所以LZ应该以二进制方式读入,如果能预先排序或者做成查找树的结构,可以直接跳过构造内存结构的过程。
    而LZ为什么要存入链表呢?一个地址指针要4个字节加上一个结束符,相当于多浪费了一倍的内存空间,而解析指针也是多余的。
    我有一个建议,你可以把二字词、三字词分别用不同的内存块。每个块里都是等长的词,连续存储(无间隔线性表),那么每个词的起始处很容易计算。这样堆就不容易碎片化的。只要你的词经过排序的话,或者建立一个索引树的话,肯定快很多。
      

  7.   

    那也没有必要,你用二进制方式打开,用_filelength(fp)就能得到文件的大小。
    不过这个是微软扩展的函数,标准C的方法是fseek(fp,0,SEEK_END);然后size=ftell(fp);就是文件的大小了。
    根据这个大小直接malloc一块空间,然后把文件整个读入。然后再进行处理。
      

  8.   

    我的内存块的意思是这样的:
    二字词表起始指针words2指向下面这个块的开始处:
    "苹果香蕉橘子......"
    三字词表起始指针words3指向下面这个块的开始处:
    ”动物园游戏机计算机......“
    当然实际的词是经过排序的,也就是将这个词无间隔的连续存储,起始就是一个大数组,地址很容易计算,
    链表是多余的。
      

  9.   

    象类似这种语法分析,语句分析什么的用映射文件来做比较好:
    1.CreateFile来打开文件
    2.CreateFileMapping建立映射文件
    3.MapViewOfFile进行视图映射
    就这三个函数行了,具体用法网上有好使的用法
      

  10.   


    谢谢你的建议,我会去尝试的! 但是现在我纠结的是建立一个索引树的问题。
    能告诉我这个索引树的结构吗?12楼说的那个FreePy我在网上没找到他的相关资料。
      

  11.   

    也可以:
    下载我的‘MyFreePy.rar’
    http://download.csdn.net/detail/schlafenhamster/1690580
      

  12.   


    能给段代码看看嘛? 网上的代码似乎都是针对64位系统的。 
    __int64 qwFileSize = 0x4000000;
    __int64 qwFileOffset = 0;
    __int64 T = 600 * sys_info.dwAllocationGranularity;