这是一段载入词库的代码 并将词库里的数据放入链表,但是效率极低,将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);//关闭词库文件。
}
#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);//关闭词库文件。
}
主要是你的数据结构不对,词库存储的方式不对,不能用文本文件。应该用一条条struct写入的二进制的记录文件,而且是应该有索引或排序的。用结构的好处时限定每个元素的长度,这样读取时就可以直接memcpy而不需要逐个字符处理。
读内存时直接转换为二叉查找树之类的,肯定效率高很多。
内存缓冲区是什么意思? 是一个变量吗? 因为我的词库是一行一个词语的。一行都是两个字的词语。 保存为TXT文档,大小大概是489KB我将这个文件中的词语一行一行的读取到链表中。 结果这段时间花了近2分钟。 FileMapping是什么?
400多K,全读到内存不算问题,解析完记得及时释放掉就行FileMapping就是文件映射,允许你像使用指针一样去操作硬盘上的文件
而LZ为什么要存入链表呢?一个地址指针要4个字节加上一个结束符,相当于多浪费了一倍的内存空间,而解析指针也是多余的。
我有一个建议,你可以把二字词、三字词分别用不同的内存块。每个块里都是等长的词,连续存储(无间隔线性表),那么每个词的起始处很容易计算。这样堆就不容易碎片化的。只要你的词经过排序的话,或者建立一个索引树的话,肯定快很多。
不过这个是微软扩展的函数,标准C的方法是fseek(fp,0,SEEK_END);然后size=ftell(fp);就是文件的大小了。
根据这个大小直接malloc一块空间,然后把文件整个读入。然后再进行处理。
二字词表起始指针words2指向下面这个块的开始处:
"苹果香蕉橘子......"
三字词表起始指针words3指向下面这个块的开始处:
”动物园游戏机计算机......“
当然实际的词是经过排序的,也就是将这个词无间隔的连续存储,起始就是一个大数组,地址很容易计算,
链表是多余的。
1.CreateFile来打开文件
2.CreateFileMapping建立映射文件
3.MapViewOfFile进行视图映射
就这三个函数行了,具体用法网上有好使的用法
谢谢你的建议,我会去尝试的! 但是现在我纠结的是建立一个索引树的问题。
能告诉我这个索引树的结构吗?12楼说的那个FreePy我在网上没找到他的相关资料。
下载我的‘MyFreePy.rar’
http://download.csdn.net/detail/schlafenhamster/1690580
能给段代码看看嘛? 网上的代码似乎都是针对64位系统的。
__int64 qwFileSize = 0x4000000;
__int64 qwFileOffset = 0;
__int64 T = 600 * sys_info.dwAllocationGranularity;