Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana untuk mengoptimumkan operasi baca dan tulis dalam pembangunan data besar C++?

Bagaimana untuk mengoptimumkan operasi baca dan tulis dalam pembangunan data besar C++?

王林
王林asal
2023-08-26 16:51:331714semak imbas

Bagaimana untuk mengoptimumkan operasi baca dan tulis dalam pembangunan data besar C++?

Bagaimana untuk mengoptimumkan operasi baca dan tulis dalam pembangunan data besar C++?

Pengenalan:
Apabila memproses data besar, operasi baca dan tulis adalah tugas biasa. Sebagai bahasa pengaturcaraan berprestasi tinggi, C++ mempunyai keupayaan untuk memproses data besar dengan cekap. Artikel ini akan memperkenalkan cara mengoptimumkan operasi baca dan tulis dalam pembangunan data besar C++ untuk meningkatkan kecekapan pelaksanaan program.

1. Gunakan pemetaan memori untuk meningkatkan kelajuan membaca dan menulis
Untuk membaca dan menulis fail data yang besar, kaedah konvensional adalah menggunakan operasi strim atau penunjuk fail untuk membaca dan menulis. Walau bagaimanapun, pendekatan ini boleh mengakibatkan pembacaan dan penulisan cakera yang kerap, mengurangkan kecekapan pelaksanaan program. Menggunakan pemetaan memori, fail boleh dipetakan terus ke dalam ingatan, dengan itu mengelakkan berbilang operasi baca dan tulis cakera.

Kod sampel:

#include <iostream>
#include <fstream>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>

#define FILE_SIZE 1024*1024*1024  // 1GB

int main() {
    int fd = open("data.bin", O_RDWR | O_CREAT | O_TRUNC, 0666);
    if (fd == -1) {
        std::cout << "Failed to open file!" << std::endl;
        return -1;
    }
    int res = lseek(fd, FILE_SIZE - 1, SEEK_SET);
    if (res == -1) {
        std::cout << "Failed to lseek!" << std::endl;
        close(fd);
        return -1;
    }
    res = write(fd, "", 1);
    if (res != 1) {
        std::cout << "Failed to write!" << std::endl;
        close(fd);
        return -1;
    }
    char* data = (char*) mmap(NULL, FILE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (data == MAP_FAILED) {
        std::cout << "Failed to mmap!" << std::endl;
        close(fd);
        return -1;
    }
    // 对于大数据文件进行读写操作
    strcpy(data, "Hello, World!");  // 写入数据
    std::cout << data << std::endl;  // 读取数据
    // 释放内存映射
    res = munmap(data, FILE_SIZE);
    if (res == -1) {
        std::cout << "Failed to munmap!" << std::endl;
        close(fd);
        return -1;
    }
    close(fd);
    return 0;
}

2. Gunakan IO tak segerak untuk meningkatkan prestasi serentak
Dalam pembangunan data besar, selalunya diperlukan untuk mengendalikan sejumlah besar operasi baca dan tulis serentak. Kaedah IO segerak tradisional akan menyebabkan setiap operasi baca dan tulis menunggu untuk operasi lain selesai, sekali gus mengurangkan kecekapan pelaksanaan program. Menggunakan kaedah IO tak segerak, anda boleh melakukan operasi lain sementara menunggu operasi tertentu selesai, dengan itu meningkatkan prestasi serentak.

Kod sampel:

#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <aio.h>
#include <unistd.h>
#include <string.h>

#define BUFFER_SIZE 1024

void read_callback(sigval_t sigval) {
    aiocb* aio = (aiocb*)sigval.sival_ptr;
    int res = aio_error(aio);
    if (res != 0) {
        std::cout << "Failed to read!" << std::endl;
    } else {
        std::cout << aio->aio_buf << std::endl;  // 输出读取的数据
    }
    aio_result(aio);
    delete aio;
}

void write_callback(sigval_t sigval) {
    aiocb* aio = (aiocb*)sigval.sival_ptr;
    int res = aio_error(aio);
    if (res != 0) {
        std::cout << "Failed to write!" << std::endl;
    }
    aio_result(aio);
    delete aio;
}

void async_read_write(const char* from, const char* to) {
    int input_fd = open(from, O_RDONLY);
    int output_fd = open(to, O_WRONLY | O_CREAT | O_TRUNC, 0666);
    
    std::vector<char> buffer(BUFFER_SIZE);
    aiocb* aio_read = new aiocb{};
    aio_read->aio_fildes = input_fd;
    aio_read->aio_buf = buffer.data();
    aio_read->aio_nbytes = BUFFER_SIZE;
    aio_read->aio_offset = 0;
    aio_read->aio_lio_opcode = LIO_READ;
    aio_read->aio_sigevent.sigev_notify = SIGEV_THREAD;
    aio_read->aio_sigevent.sigev_notify_function = read_callback;
    aio_read->aio_sigevent.sigev_value.sival_ptr = aio_read;
    
    aiocb* aio_write = new aiocb{};
    aio_write->aio_fildes = output_fd;
    aio_write->aio_buf = buffer.data();
    aio_write->aio_nbytes = BUFFER_SIZE;
    aio_write->aio_offset = 0;
    aio_write->aio_lio_opcode = LIO_WRITE;
    aio_write->aio_sigevent.sigev_notify = SIGEV_THREAD;
    aio_write->aio_sigevent.sigev_notify_function = write_callback;
    aio_write->aio_sigevent.sigev_value.sival_ptr = aio_write;
    
    std::vector<aiocb*> aiocb_list = {aio_read, aio_write};
    lio_listio(LIO_WAIT, aiocb_list.data(), aiocb_list.size(), nullptr);
    
    close(input_fd);
    close(output_fd);
}

int main() {
    async_read_write("data.bin", "data_copy.bin");
    return 0;
}

Kesimpulan:
Dengan menggunakan pemetaan memori dan IO tak segerak, kecekapan pelaksanaan operasi baca dan tulis dalam pembangunan data besar C++ boleh dipertingkatkan dengan berkesan. Terutama untuk fail besar atau senario yang perlu mengendalikan sejumlah besar baca dan tulis serentak, kaedah pengoptimuman ini akan dapat memberikan permainan sepenuhnya kepada kelebihan terbesar mereka dan meningkatkan prestasi program.

Nota: Untuk memudahkan pemahaman, kod sampel hanyalah titik permulaan Dalam pembangunan sebenar, kod perlu direka bentuk dan dioptimumkan mengikut keperluan perniagaan tertentu, dan ujian dan pengoptimuman prestasi perlu dijalankan mengikut. keadaan sebenar.

Atas ialah kandungan terperinci Bagaimana untuk mengoptimumkan operasi baca dan tulis dalam pembangunan data besar C++?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn