【发布时间】: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();
}
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();
}
但令人难以置信的是,第二个代码生成矩阵的速度要慢得多
当我使用 printf("%s", readLine) 打印来自 getline func 的 readLine 时,它会打印奇怪的字符,无论如何,当我将 readLine 附加到字符串数组元素时,这些奇怪的字符会在控制台上发生变化,我猜这就是为什么我的性能会变慢,因为函数 line str.find(" ") 或 stod(str) 与第一个怪异的函数相比,第二个函数的效果更好
如果你有同样的想法,你可能会建议一种方法来防止附加字符发生变化
【问题讨论】:
-
如果不看到至少一些代码,几乎不可能回答。
-
假设
readLine是std::string,printf("%s", readLine)表现出未定义的行为。首先,%s说明符需要char*作为对应的参数,其次,不能将非 POD 类(例如std::string)传递给可变参数函数(例如printf)。 -
@IgorTandetnik 抱歉我的 c++ 知识不好,我在这个 lang 中没有那么多 exp,但我使用 printf 进行测试,问题出在其他地方
-
我编辑了这个问题,这样代码就可以直接看到,而无需点击链接。将来尝试为您发布的问题/答案这样做。
-
另外,你说一个版本要慢得多。你是如何测量这个的?请将其添加到问题中。
标签: c++