相关疑难解决方法(0)

以合理,安全和有效的方式复制文件

我搜索一个复制文件(二进制或文本)的好方法.我写过几个样本,每个人都在工作.但我想听听经验丰富的程序员的意见.

我错过了很好的例子并搜索了一种适用于C++的方法.

ANSI-C-WAY

#include <iostream>
#include <cstdio>    // fopen, fclose, fread, fwrite, BUFSIZ
#include <ctime>
using namespace std;

int main() {
    clock_t start, end;
    start = clock();

    // BUFSIZE default is 8192 bytes
    // BUFSIZE of 1 means one chareter at time
    // good values should fit to blocksize, like 1024 or 4096
    // higher values reduce number of system calls
    // size_t BUFFER_SIZE = 4096;

    char buf[BUFSIZ];
    size_t size;

    FILE* source = fopen("from.ogv", "rb");
    FILE* dest = fopen("to.ogv", "wb"); …
Run Code Online (Sandbox Code Playgroud)

c++ file-io

292
推荐指数
4
解决办法
18万
查看次数

我什么时候应该使用mmap进行文件访问?

POSIX环境提供至少两种访问文件的方法.有标准的系统调用open(),read(),write(),和朋友,但也有使用的选项mmap(),将文件映射到虚拟内存.

何时优先使用一个而不是另一个?它们各自的优势是什么,包括两个接口?

c file-io posix mmap

263
推荐指数
6
解决办法
10万
查看次数

C++标准是否要求iostream的性能不佳,或者我只是处理糟糕的实现?

每当我提到C++标准库iostream的慢性能时,我都会遇到一阵难以置信的风潮.然而,我有剖析器结果显示在iostream库代码中花费了大量时间(完全编译器优化),并且从iostream切换到特定于操作系统的I/O API和自定义缓冲区管理确实提供了一个数量级的改进.

C++标准库做了多少额外工作,标准是否需要它,它在实践中是否有用?或者有些编译器提供了与手动缓冲区管理竞争的iostream实现吗?

基准

为了解决问题,我编写了几个简短的程序来练习iostreams内部缓冲:

请注意,ostringstreamstringbuf版本运行的迭代次数较少,因为它们的速度要慢得多.

在ideone上,它ostringstreamstd:copy+ back_inserter+ 慢大约3倍std::vector,比memcpy原始缓冲区慢大约15倍.当我将实际应用程序切换到自定义缓冲时,这与前后分析一致.

这些都是内存缓冲区,因此iostream的缓慢不能归咎于缓慢的磁盘I/O,过多的刷新,与stdio的同步,或者人们用来解释C++标准库观察到的缓慢的任何其他事情iostream的.

很高兴看到其他系统上的基准测试和常见实现的评论(例如gcc的libc ++,Visual C++,Intel C++)以及标准规定了多少开销.

此测试的基本原理

许多人都正确地指出,iostream更常用于格式化输出.但是,它们也是C++标准提供的二进制文件访问的唯一现代API.但是对内部缓冲进行性能测试的真正原因适用于典型的格式化I/O:如果iostreams无法保持磁盘控制器提供原始数据,那么当他们负责格式化时,他们怎么可能跟上呢?

基准时间

所有这些都是outer(k)循环的每次迭代.

在ideone上(gcc-4.3.4,未知的操作系统和硬件):

  • ostringstream:53毫秒
  • stringbuf:27毫秒
  • vector<char>并且back_inserter:17.6毫秒
  • vector<char> 与普通迭代器:10.6毫秒
  • vector<char> 迭代器和边界检查:11.4 ms
  • char[]:3.7毫秒

在我的笔记本电脑上(Visual C++ 2010 x86,cl …

c++ performance iostream

193
推荐指数
3
解决办法
2万
查看次数

为什么std :: fstreams这么慢?

我正在研究一个简单的解析器,在进行分析时我发现瓶颈在...文件读取!我摘录了非常简单的测试来比较的性能fstreamsFILE*读取数据的大斑点时:

#include <stdio.h>
#include <chrono>
#include <fstream>
#include <iostream>
#include <functional>

void measure(const std::string& test, std::function<void()> function)
{
    auto start_time = std::chrono::high_resolution_clock::now();

    function();

    auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - start_time);
    std::cout<<test<<" "<<static_cast<double>(duration.count()) * 0.000001<<" ms"<<std::endl;
}

#define BUFFER_SIZE (1024 * 1024 * 1024)

int main(int argc, const char * argv[])
{
    auto buffer = new char[BUFFER_SIZE];
    memset(buffer, 123, BUFFER_SIZE);

    measure("FILE* write", [buffer]()
    {
        FILE* file = fopen("test_file_write", "wb");
        fwrite(buffer, 1, BUFFER_SIZE, file);
        fclose(file);
    });
    measure("FILE* read", [buffer]() …
Run Code Online (Sandbox Code Playgroud)

c++ performance

38
推荐指数
2
解决办法
1万
查看次数

内存映射文件有多大?

什么限制了内存映射文件的大小?我知道它不能超过最大的连续未分配地址空间块,并且应该有足够的可用磁盘空间.但还有其他限制吗?

mmap memory-mapped-files

24
推荐指数
2
解决办法
2万
查看次数

C和C++样式文件IO之间的性能差异

我一直听说C++文件I/O操作比C风格I/O慢得多.但我没有找到任何实际的参考文件,因为它们实际上有多慢,所以我决定在我的机器上测试它(Ubuntu 12.04,GCC 4.6.3,ext4分区格式).

首先,我在磁盘中写了一个~900MB的文件.

C++(ofstream):163s

ofstream file("test.txt");

for(register int i = 0; i < 100000000; i++) 
    file << i << endl;
Run Code Online (Sandbox Code Playgroud)

C(fprintf):12s

FILE *fp = fopen("test.txt", "w");

for(register int i = 0; i < 100000000; i++) 
    fprintf(fp, "%d\n", i);
Run Code Online (Sandbox Code Playgroud)

我期待这样的输出,它表明在C++ C中写入文件要慢得多.然后我使用C和C++ I/O读取相同的文件.让我感到惊讶的是,从文件中读取时,性能几乎没有差异.

C++(ifstream):12s

int n;
ifstream file("test.txt");

for(register int i = 0; i < 100000000; i++) 
    file >> n;
Run Code Online (Sandbox Code Playgroud)

C(fscanf):12s

FILE *fp = fopen("test.txt", "r");

for(register int i = 0; i < …
Run Code Online (Sandbox Code Playgroud)

c c++ file-io stream

24
推荐指数
2
解决办法
8766
查看次数

为什么我的C++磁盘写入测试比使用bash的简单文件复制要慢得多?

使用下面的程序我尝试测试我可以用多快的速度写入磁盘std::ofstream.

在写入1 GiB文件时,我达到大约300 MiB/s.

但是,使用该cp命令的简单文件复制速度至少快两倍.

我的程序是否达到了硬件限制,还是可以更快?

#include <chrono>
#include <iostream>
#include <fstream>

char payload[1000 * 1000]; // 1 MB

void test(int MB)
{
    // Configure buffer
    char buffer[32 * 1000];
    std::ofstream of("test.file");
    of.rdbuf()->pubsetbuf(buffer, sizeof(buffer));

    auto start_time = std::chrono::steady_clock::now();

    // Write a total of 1 GB
    for (auto i = 0; i != MB; ++i)
    {
        of.write(payload, sizeof(payload));
    }

    double elapsed_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now() - start_time).count();
    double megabytes_per_ns = 1e3 / elapsed_ns;
    double megabytes_per_s = 1e9 * megabytes_per_ns; …
Run Code Online (Sandbox Code Playgroud)

c++ performance fstream

14
推荐指数
2
解决办法
1225
查看次数

使用ofstream进行缓冲文本输出以获得性能

我需要编写一个程序,它将在输出文件中写入许多字符.我的程序还需要编写换行符以便更好地格式化.我理解ofstream是一个缓冲流,如果我们使用缓冲流文件io,我们获得了性能.但是,如果我们使用std::endl输出将被刷新,并且由于缓冲输出,我们将失去任何潜在的性能增益.

我想如果我使用'\n'新行,输出将只在我们将要刷新时刷新std::endl.它是否正确?是否有任何技巧可用于在文件输出期间获得性能提升?

注意:我想在文件写入操作完成时刷新缓冲输出.我认为通过这种方式,我可以最小化文件I/O,从而获得性能.

c++ performance file-io

9
推荐指数
1
解决办法
9989
查看次数

在不使用iostream的情况下保存c ++ 11随机生成器的状态

在不使用iostream接口的情况下,存储C++ 11随机生成器状态的最佳方法是什么.我想像这里列出的第一个替代品那样做[1]?但是,此方法要求对象包含PRNG状态且仅包含PRNG状态.在partucular,它如果实现使用PIMPL模式失败(至少这是有可能重新加载状态,而不是用坏的数据加载它,当应用程序崩溃),或有与没有的PRNG对象相关联的多个状态变量与生成的序列有关.

对象的大小实现定义的:

我缺少像这样的成员函数

  1. size_t state_size();
  2. const size_t* get_state() const;
  3. void set_state(size_t n_elems,const size_t* state_new);

(1)应返回随机生成器状态数组的大小

(2)应返回指向状态数组的指针.指针由PRNG管理.

(3)应从std::min(n_elems,state_size())state_new指向的缓冲区中复制缓冲区

这种接口允许更灵活的状态操作.或者是否有任何PRNG:s的状态不能表示为无符号整数数组?

[1] 比使用流来节省增强随机生成器状态更快

random c++11

6
推荐指数
1
解决办法
410
查看次数

如何将C++写入速度提升到CrystalDiskMark测试的速度?

现在我在内存中每秒获得大约3.6GB的数据,我需要不断地在我的SSD上写它们.我使用CrystalDiskMark来测试我的SSD的写入速度,它几乎是每秒6GB,所以我认为这项工作不应该那么难.

![我的SSD测试结果] [1]:

[1] https://plus.google.com/u/0/photos/photo/106876803948041178149/6649598887699308850?authkey=CNbb5KjF8-jxJQ "测试结果":

我的电脑是Windows 10,使用Visual Studio 2017社区.

我找到了这个问题,并尝试了最高的投票答案.不幸的是,他的option_2的写入速度仅为1s/GB,远远低于CrystalDiskMark所测试的速度.然后我尝试了内存映射,这次写入变得更快,大约630ms/GB,但仍然慢得多.然后我尝试了多线程内存映射,似乎当线程数为4时,速度约为350ms/GB,当我添加线程数时,写入速度不再上升.

内存映射代码:

#include <fstream>
#include <chrono>
#include <vector>
#include <cstdint>
#include <numeric>
#include <random>
#include <algorithm>
#include <iostream>
#include <cassert>
#include <thread>
#include <windows.h>
#include <sstream>


// Generate random data
std::vector<int> GenerateData(std::size_t bytes) {
    assert(bytes % sizeof(int) == 0);
    std::vector<int> data(bytes / sizeof(int));
    std::iota(data.begin(), data.end(), 0);
    std::shuffle(data.begin(), data.end(), std::mt19937{ std::random_device{}() });
    return data;
}

// Memory mapping
int map_write(int* data, int size, int id){
    char* name = (char*)malloc(100); …
Run Code Online (Sandbox Code Playgroud)

c++ file-writing

6
推荐指数
2
解决办法
387
查看次数