载入文档很慢 要近二分多钟

载入文档很慢 要近2分多钟
这是一段载入词库的代码 并将词库里的数据放入链表,但是效率极低,将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.CreateFile来打开文件
2.CreateFileMapping建立映射文件
3.MapViewOfFile进行视图映射
就这三个函数行了,具体用法网上有好使的用法

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

不见得吧,虽然windows有缓存机制,可是依赖于未文档化的缓存并不可靠

建议试试一次读完,然后解析

如果这样还觉得慢,那干脆直接用FileMapping吧
------其他解决方案--------------------
那也没有必要,你用二进制方式打开,用_filelength(fp)就能得到文件的大小。
不过这个是微软扩展的函数,标准C的方法是fseek(fp,0,SEEK_END);然后size=ftell(fp);就是文件的大小了。
根据这个大小直接malloc一块空间,然后把文件整个读入。然后再进行处理。
------其他解决方案--------------------
我的内存块的意思是这样的:
二字词表起始指针words2指向下面这个块的开始处:
"苹果香蕉橘子......"
三字词表起始指针words3指向下面这个块的开始处:
”动物园游戏机计算机......“
当然实际的词是经过排序的,也就是将这个词无间隔的连续存储,起始就是一个大数组,地址很容易计算,
链表是多余的。
------其他解决方案--------------------
你一次读取到内存缓冲区中,然后再解析数据不行吗?
------其他解决方案--------------------
“将词库里的数据放入链表”是指用户的常规操作--装载词库么?

    while(!feof(file)    循环中,你到底想做什么,为什么这么写?
------其他解决方案--------------------
其实2楼说的那样,速度应该差不多,因为Windows是由缓存机制的,所以就算你不读到内存缓冲区,还是相当于在内存解析。
主要是你的数据结构不对,词库存储的方式不对,不能用文本文件。应该用一条条struct写入的二进制的记录文件,而且是应该有索引或排序的。用结构的好处时限定每个元素的长度,这样读取时就可以直接memcpy而不需要逐个字符处理。
读内存时直接转换为二叉查找树之类的,肯定效率高很多。
------其他解决方案--------------------
个人估计时间是花在了fget上
400多K,全读到内存不算问题,解析完记得及时释放掉就行

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