静态向量在递归函数中比全局慢得多
static vector much slower than global in recursive function
我想用静态变量代替全局变量,发现比以前慢多了。原来的代码只用了不到 0.01 秒,现在大约需要 1.6 秒。
我不熟悉矢量。有没有一种简单的方法可以获得与以前相同的性能?
#include <cstdio>
#include <cmath>
#include <ctime>
#include <vector>
using namespace std;
vector<double> fun(double x1, double y1, double x5, double y5, int i)
{
static vector<double> vec;
double x2 = (2 * x1 + x5) / 3;
double y2 = (2 * y1 + y5) / 3;
double x3 = (x1 + x5) / 2. + (y1 - y5) / (2. * sqrt(3));
double y3 = (-x1 + x5) / (2. * sqrt(3)) + (y1 + y5) / 2.;
double x4 = (x1 + 2 * x5) / 3;
double y4 = (y1 + 2 * y5) / 3.;
if (i <= 1)
{
vec.push_back(x1);
vec.push_back(y1);
vec.push_back(x2);
vec.push_back(y2);
vec.push_back(x3);
vec.push_back(y3);
vec.push_back(x4);
vec.push_back(y4);
vec.push_back(x5);
vec.push_back(y5);
}
else
{
fun(x1, y1, x2, y2, i - 1);
fun(x2, y2, x3, y3, i - 1);
fun(x3, y3, x4, y4, i - 1);
fun(x4, y4, x5, y5, i - 1);
}
return vec;
}
int main(int argC, char** argV)
{
clock_t t0 = clock();
int n = 8;
vector<double> vec = fun(0, 0, 1, 0, n);
printf("%d\n", vec.size());
printf("time %0.4fs\n", (clock() - t0) / 1000.0);
return 0;
}
有两个因素,
- 次要因素是每次函数进入时,程序都会检查变量是否已经初始化(而且必须是线程安全的)
- 主要因素是您从每次调用中返回向量的副本,即使您几乎忽略了所有调用。 (有 21,845 个矢量副本,每个都涉及内存分配和释放,总共有 1,790,197,760
double
被复制。这将近 15 GB。)
解决性能问题和只能解决一次问题的简单方法是将结果累加到参考参数中:
void fun(double x1, double y1, double x5, double y5, int i, vector<double>& vec)
并从 fun
中删除本地 vec
,然后在 main
、
vector<double> vec;
fun(0, 0, 1, 0, n, vec);
无需进行其他更改。
我想用静态变量代替全局变量,发现比以前慢多了。原来的代码只用了不到 0.01 秒,现在大约需要 1.6 秒。 我不熟悉矢量。有没有一种简单的方法可以获得与以前相同的性能?
#include <cstdio>
#include <cmath>
#include <ctime>
#include <vector>
using namespace std;
vector<double> fun(double x1, double y1, double x5, double y5, int i)
{
static vector<double> vec;
double x2 = (2 * x1 + x5) / 3;
double y2 = (2 * y1 + y5) / 3;
double x3 = (x1 + x5) / 2. + (y1 - y5) / (2. * sqrt(3));
double y3 = (-x1 + x5) / (2. * sqrt(3)) + (y1 + y5) / 2.;
double x4 = (x1 + 2 * x5) / 3;
double y4 = (y1 + 2 * y5) / 3.;
if (i <= 1)
{
vec.push_back(x1);
vec.push_back(y1);
vec.push_back(x2);
vec.push_back(y2);
vec.push_back(x3);
vec.push_back(y3);
vec.push_back(x4);
vec.push_back(y4);
vec.push_back(x5);
vec.push_back(y5);
}
else
{
fun(x1, y1, x2, y2, i - 1);
fun(x2, y2, x3, y3, i - 1);
fun(x3, y3, x4, y4, i - 1);
fun(x4, y4, x5, y5, i - 1);
}
return vec;
}
int main(int argC, char** argV)
{
clock_t t0 = clock();
int n = 8;
vector<double> vec = fun(0, 0, 1, 0, n);
printf("%d\n", vec.size());
printf("time %0.4fs\n", (clock() - t0) / 1000.0);
return 0;
}
有两个因素,
- 次要因素是每次函数进入时,程序都会检查变量是否已经初始化(而且必须是线程安全的)
- 主要因素是您从每次调用中返回向量的副本,即使您几乎忽略了所有调用。 (有 21,845 个矢量副本,每个都涉及内存分配和释放,总共有 1,790,197,760
double
被复制。这将近 15 GB。)
解决性能问题和只能解决一次问题的简单方法是将结果累加到参考参数中:
void fun(double x1, double y1, double x5, double y5, int i, vector<double>& vec)
并从 fun
中删除本地 vec
,然后在 main
、
vector<double> vec;
fun(0, 0, 1, 0, n, vec);
无需进行其他更改。