我有一个2 GB的文件(iputfile.txt),其中文件中的每一行都是一个单词,就像:
apple
red
beautiful
smell
spark
input
Run Code Online (Sandbox Code Playgroud)
我需要编写一个程序来读取文件中的每个单词并打印单词计数.我使用Java和C++编写它,但结果令人惊讶:Java运行速度比C++快2.3倍.我的代码如下:
C++:
int main() {
struct timespec ts, te;
double cost;
clock_gettime(CLOCK_REALTIME, &ts);
ifstream fin("inputfile.txt");
string word;
int count = 0;
while(fin >> word) {
count++;
}
cout << count << endl;
clock_gettime(CLOCK_REALTIME, &te);
cost = te.tv_sec - ts.tv_sec + (double)(te.tv_nsec-ts.tv_nsec)/NANO;
printf("Run time: %-15.10f s\n", cost);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
5e+08
Run time: 69.311 s
Run Code Online (Sandbox Code Playgroud)
Java的:
public static void main(String[] args) throws Exception {
long startTime = System.currentTimeMillis();
FileReader reader …Run Code Online (Sandbox Code Playgroud) 我有一个包含数百万行的文件,每行有3个以空格分隔的浮点数.读取文件需要花费大量时间,因此我尝试使用内存映射文件读取它们,但发现问题不在于IO的速度,而在于解析速度.
我当前的解析是获取流(称为文件)并执行以下操作
float x,y,z;
file >> x >> y >> z;
Run Code Online (Sandbox Code Playgroud)
Stack Overflow中的某些人建议使用Boost.Spirit,但我找不到任何简单的教程来解释如何使用它.
我正在尝试找到一种简单有效的方法来解析看起来像这样的行:
"134.32 3545.87 3425"
Run Code Online (Sandbox Code Playgroud)
我真的很感激一些帮助.我想用strtok来分割它,但我不知道如何将字符串转换为浮点数,我不太确定它是最好的方法.
我不介意解决方案是否会提升.我不介意它是不是有史以来最有效的解决方案,但我确信它可以加倍速度.
提前致谢.
我正在使用VS2010编写一个C++程序来读取文本文件并从中提取某些信息.我使用filestream完成了代码,效果很好.但是现在我被要求将文件映射到内存并使用它而不是文件操作.
在内存映射的情况下,我绝对是一个新手.我写的代码的一部分如下.
boost::iostreams::mapped_file_source apifile;
apifile.open(LogFileName,LogFileSize);
if(!apifile.is_open())
return FILE_OPEN_ERROR;
// Get pointer to the data.
PBYTE Buffer = (PBYTE)apifile.data();
while(//read till end of the file)
{
// read a line and check if it contains a specific word
}
Run Code Online (Sandbox Code Playgroud)
在使用FILESTREAM我会用eof与getline和string::find用于执行操作.但我不知道如何使用内存映射文件来做到这一点.
编辑1:
int ProcessLogFile(string file_name)
{
LogFileName = file_name;
apifile.open(LogFileName);//boost::iostreams::mapped_file_source apifile(declared globally)
streamReader.open(apifile, std::ios::binary);//boost::iostreams::stream <boost::iostreams::mapped_file_source> streamReader(declared globally)
streamoff Curr_Offset = 0;
string read_line;
int session_id = 0;
int device_id = 0;
while(!streamReader.eof())
{
\\COLLECT OFFSETS OF …Run Code Online (Sandbox Code Playgroud) http://insanecoding.blogspot.co.uk/2011/11/how-to-read-in-file-in-c.html回顾了在C++中将整个文件读入字符串的多种方法.最快选项的关键代码如下所示:
std::string contents;
in.seekg(0, std::ios::end);
contents.resize(in.tellg());
in.seekg(0, std::ios::beg);
in.read(&contents[0], contents.size());
Run Code Online (Sandbox Code Playgroud)
不幸的是,这不安全,因为它依赖string于以特定方式实施.例如,如果实现是共享字符串,那么修改数据&contents[0]可能会影响正在读取的字符串之外的字符串.(更一般地说,不能保证这不会破坏任意记忆 - 在实践中不太可能发生,但依靠它不是好习惯.)
C++和STL旨在提供高效的C语言功能,因此可以预期上述版本的速度同样快,但保证安全.
在这种情况下vector<T>,有一些函数可用于访问原始数据,可用于有效地读取向量:
T* vector::data();
const T* vector::data() const;
Run Code Online (Sandbox Code Playgroud)
其中第一个可以用来vector<T>有效地阅读.不幸的是,string等价物只提供了const变体:
const char* string::data() const noexcept;
Run Code Online (Sandbox Code Playgroud)
所以这不能用于有效地读取字符串.(可能non-const省略了变体以支持共享字符串实现.)
我还检查了字符串构造函数,但接受char*复制数据的那些 - 没有选项可以移动它.
有没有一种安全快捷的方法将文件的全部内容读入字符串?
值得注意的是,我想读取一个string而不是一个,vector<char>以便我可以使用a来访问结果数据istringstream.没有相同的vector<char>.
我读sehe的回答到这个问题,并惊讶地看到使用使用手写环发现sehe std::memchr要快3倍还比使用std::count(见注释).使用的代码std::count可以在编辑2中看到,但它基本上归结为:
const auto num_lines = std::count(f, l, '\n');
Run Code Online (Sandbox Code Playgroud)
VS
uintmax_t num_lines = 0;
while (f && f != l)
if ((f = static_cast<const char*>(memchr(f, '\n', l - f))))
num_lines++, f++;
Run Code Online (Sandbox Code Playgroud)
我原本期望std::count版本至少和那个版本一样快std::memchr- 出于类似的原因,为什么使用它std::copy应该至少和它一样快std::memcpy.
我检查了我的标准库(libc ++)的实现std::count,并没有尝试优化char输入类型(同上std::find).
为什么是这样?std::memchr如果提供char*迭代器和char值,实现是否可以不调度?
在我的情况下,我有不同的文件让我们假设我有4GB文件的数据.我想逐行读取该文件并处理每一行.我的一个限制是软件必须在32位MS Windows上运行,或者在64位上运行少量RAM(最小4GB).您还可以假设这些行的处理不是瓶颈.
在当前的解决方案中,我读取该文件ifstream并复制到某个字符串.这是片段的样子.
std::ifstream file(filename_xml.c_str());
uintmax_t m_numLines = 0;
std::string str;
while (std::getline(file, str))
{
m_numLines++;
}
Run Code Online (Sandbox Code Playgroud)
好的,这是有效的,但在这里慢慢地是我的3.6 GB数据的时间:
real 1m4.155s
user 0m0.000s
sys 0m0.030s
Run Code Online (Sandbox Code Playgroud)
我正在寻找一种比这更快的方法,例如我发现如何快速解析C++中空格分隔的浮点数?我喜欢用boost :: mapped_file提出解决方案,但我遇到了另一个问题,如果我的文件是大的,在我的情况下文件1GB大到足以放弃整个过程.我不得不关心内存中的当前数据,可能使用该工具的人的RAM安装量不超过4 GB.
所以我发现了来自boost的mapped_file但是在我的情况下如何使用它?是否可以部分读取该文件并接收这些行?
也许你有另一个更好的解决方案.我必须处理每一行.
谢谢,
巴特
简单的问题:如果我有一个boost :: filesystem :: path对象,我怎样才能得到这个文件的行数?我需要比较两个文件的行数作为前置条件检查.
我是新手,并且最近习惯于使用Java编程.我在网上搜索过,但却找不到这么简单的任务的例子.
非常感谢!
我目前使用带有scanf的循环("%d",&value),但我需要它更快.数据量可高达2 000 000个值.有什么方法可以加快速度吗?我读到了strtok和strtol,但我不知道如何使用它们,如果它们甚至可以达到我需要的速度.
c++ ×7
boost ×3
file ×2
32-bit ×1
boost-spirit ×1
c ×1
java ×1
large-files ×1
memory ×1
parsing ×1
performance ×1
stl ×1
string ×1