【问题标题】:c++ getline file output change when is copied to stringc ++ getline文件输出更改时复制到字符串
【发布时间】:2020-08-01 21:07:54
【问题描述】:

我有一个文件,它的每一行都有一行矩阵,并且在每一行中,双数之间有空格,这个文件包括很多这样的矩阵,它们之间有一个空行

现在我有两个不同版本的代码:

1-单线程用getline(file, readLine)从文件中读取,直接处理readLine,拆分后用stod做双数,做矩阵

#include <fstream>
#include <string>

using namespace std;

void decomposeSerial(double *A, long n)
{
    long i, j, k;
    for (k = 0; k < n; k++) {
        for (j = k + 1; j < n; j++)
            A[k*n + j] = A[k*n + j] / A[k*n + k];

        for (i = k + 1; i < n; i++)
            for (j = k + 1; j < n; j++)
                A[i*n + j] = A[i*n + j] - A[i*n + k] * A[k*n + j];
    }
}

void main() {
    const string inFilePath = ".\\data_in\\file.txt";
    const string outFilePath = ".\\data_out\\file.txt";
    ifstream inFile(inFilePath);
    ofstream outFile(outFilePath);
    int n;
    int matrixLine = 0;
    double * matrix = NULL;
    string readLine;
    while (getline(inFile, readLine)) {
        if (!readLine.empty()) {
            if (matrixLine == 0) {
                n = 0;
                string temp = readLine;
                size_t pos = 0;
                while ((pos = temp.find(" ")) != string::npos) {
                    temp.erase(0, pos + 1);
                    n++;
                }
                matrix = (double *)malloc(sizeof(double) * n * n);
            }
            size_t pos = 0;
            string token;
            int i = 0;
            while ((pos = readLine.find(" ")) != string::npos) {
                token = readLine.substr(0, pos);
                matrix[matrixLine * n + i] = stod(token);
                readLine.erase(0, pos + 1);
                i++;
            }
            matrixLine++;
            if (matrixLine == n) {
                decomposeSerial(matrix, n);
                double det = 1;
                for (long o = 0; o < n; o++) {
                    det *= matrix[o * n + o];
                }
                outFile << det << "\n";
            }
        }
        else {
            matrixLine = 0;
        }
    }
    inFile.close();
    outFile.close();
}

http://codeshare.io/5enk9x

2- 使用 getline(file, readLine) 从文件中读取单线程并将 readLine 附加到专用于该矩阵的字符串数组的元素中,然后,并行地,每个线程获取这些元素之一并通过制作矩阵的过程相同

#include <fstream>
#include <string>
#include <omp.h>

using namespace std;

double det[1000];
string input[1000];
int ns[1000];

void computation(double* src, int n, int l)
{
    long i, j, k;
    for (k = 0; k < n; k++) {
        for (j = k + 1; j < n; j++)
            src[k*n + j] = src[k*n + j] / src[k*n + k];

        for (i = k + 1; i < n; i++)
            for (j = k + 1; j < n; j++)
                src[i*n + j] = src[i*n + j] - src[i*n + k] * src[k*n + j];
    }
    double res = 1;
    for (int j = 0; j < n; j++) {
        res *= src[j*n + j];
    }
    det[l] = res;
}

void main() {
    const string inFilePath = ".\\data_in\\file.txt";
    const string outFilePath = ".\\data_out\\file.txt";
    ifstream inFile(inFilePath);
    int matrixCount = 0;
    bool inMatrix = false;
    string readLine;
    int dim = 0;
    while (getline(inFile, readLine)) {
        dim++;
        if (readLine.empty()) {
            ns[matrixCount] = dim - 1;
            dim = 0;
            inMatrix = false;
            matrixCount++;
        }
        else {
            if (inMatrix == false) {
                inMatrix = true;
                input[matrixCount] = readLine;
            }
            else {
                input[matrixCount] += readLine;
            }
        }
    }
    ns[matrixCount] = dim;
    matrixCount++;
    inFile.close();
#pragma omp parallel
    {
#pragma omp for schedule(dynamic)
        for (int i = 0; i < matrixCount; i++) {
            string matrixStr = input[i];
            int n = ns[i];
            double * matrix = (double *)malloc(sizeof(double) * n * n);
            size_t pos = 0;
            string token;
            int k = 0;
            while ((pos = matrixStr.find(" ")) != string::npos) {
                token = matrixStr.substr(0, pos);
                matrix[k] = stod(token);
                matrixStr.erase(0, pos + 1);
                k++;
            }
            computation(matrix, n, i);

            free(matrix);
        }
    }
    ofstream outFile(outFilePath);
    for (int i = 0; i < matrixCount; i++) {
        outFile << det[i] << "\n";
    }
    outFile.close();
}

http://codeshare.io/ad83Yy

但令人难以置信的是,第二个代码生成矩阵的速度要慢得多

当我使用 printf("%s", readLine) 打印来自 getline func 的 readLine 时,它​​会打印奇怪的字符,无论如何,当我将 readLine 附加到字符串数组元素时,这些奇怪的字符会在控制台上发生变化,我猜这就是为什么我的性能会变慢,因为函数 line str.find(" ") 或 stod(str) 与第一个怪异的函数相比,第二个函数的效果更好

如果你有同样的想法,你可能会建议一种方法来防止附加字符发生变化

【问题讨论】:

  • 如果不看到至少一些代码,几乎不可能回答。
  • 假设readLinestd::stringprintf("%s", readLine) 表现出未定义的行为。首先,%s 说明符需要 char* 作为对应的参数,其次,不能将非 POD 类(例如 std::string)传递给可变参数函数(例如 printf)。
  • @IgorTandetnik 抱歉我的 c++ 知识不好,我在这个 lang 中没有那么多 exp,但我使用 printf 进行测试,问题出在其他地方
  • 我编辑了这个问题,这样代码就可以直接看到,而无需点击链接。将来尝试为您发布的问题/答案这样做。
  • 另外,你说一个版本要慢得多。你是如何测量这个的?请将其添加到问题中。

标签: c++


【解决方案1】:

这些类型的性能问题无法推理。您需要使用分析器并测量代码的哪些部分占用了多少时间。

首先,我会让两个代码更相似。有很多差异可能会混淆这个问题(曾经版本 1 存在巨大的内存泄漏)。

【讨论】:

  • 唯一的巨大区别是#pragma 可以被评论,它仍然是一样的,关于内存泄漏,是的,我不知道这个语言的垃圾收集器,但问题是相反的考虑到这些代码,我应该填写一份报告,我宁愿不改变
猜你喜欢
  • 2012-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-30
  • 1970-01-01
  • 2020-03-25
  • 1970-01-01
相关资源
最近更新 更多