我正在开发ac app,它从mysql表读取数据,处理它然后将它插入到oracle数据库中的100个不同的表中.问题在于应用程序的性能存在巨大问题.在我提到的mysql表中,有4,800,000个,其中有92列.90个主题只是整数.因此,在我的应用程序中,每个条目为4,800,000,我正在运行for循环,如下所示.
for (col = 1; col < 92; col++) { if (row[col] != NULL) { sum += strtol(row[col], NULL, 10); } else sum = sum + 0; if (col == 14) { p1_2weeks = sum; } else if (col == 31) { p2_1month = sum; } else if (col == 90) { p3_2month = sum; } }
因此,由于这会运行大量的迭代,我相信我可能会减少使用常规添加来执行此操作所花费的时间.
p1_2weeks = strtol(row[1], NULL, 10) + strtol(row[2], NULL, 10) + ... + strtol(row[14], NULL, 10); p2_1months = p1_2weeks + strtol(row[15], NULL, 10) + ... + strtol(row[31], NULL, 10); p3_3months = p2_1months + strtol(row[32], NULL, 10) + ... + strtol(row[91], NULL, 10);
那么有人可以建议哪一个更好或者其他一些方法做得对.
一个for
有明确的新增循环或手动展开是不会让一个显著差异.大部分时间都花在从MySQL读取并将字段转换为字符串,并将结果插入Oracle中.如果程序花费99%的时间在数据库代码中,这不会让我感到惊讶,优化这个循环将是一个没有实际意义的点.
您可能希望寻找一种不同的方法来从MySQL中提取不会将整数转换为字符串的值.
分析将告诉您编译器/选项/ cpu/memory/dataset的给定组合的瓶颈在哪里,但是告诉您在程序中花费的时间以及等待Oracle进程或MySQL连接所花费的时间可能很棘手.经过的时间是最后的判断.
请注意,您提议的替代方法在语义上不等效:在显式添加的序列中,您不测试NULL
字段.如果列不能NULL
,则可以删除if (row[col] != NULL)
测试,如果可以NULL
,则必须修改添加以添加更多测试,这将使其非常笨拙.此外,正如seleciii44所暗示的那样,提出的替代方案会生成更大的代码,这也会产生影响.
节点也表示循环非常简单,而添加序列容易出错:很容易产生剪切和粘贴错误并错过索引或重复索引.如果你去添加,请使用代码布局,使索引清晰.看看我如何重新格式化你的代码.
实际上你在循环(p2_1month
/ p2_1months
,p3_2month
/ p3_3months
)中有拼写错误,并且加法不会p3_3months
以相同的方式计算:循环总和90
天数,其中加法总和91
天数.但当然,一个季度的天数从几天89
到92
几天不等.
另请注意sum = sum + 0;
,应该删除的是无操作,但编译器很可能不会为其生成代码.
如果您关注每次迭代执行的额外测试14,31和90天,您可以使用:
long temp[92]; for (col = 1; col < 92; col++) { if (row[col] != NULL) { sum += strtol(row[col], NULL, 10); } temp[col] = sum; } p1_2weeks = temp[14]; p2_1month = temp[31]; p3_3months = temp[90];
它可能比带有测试的版本更有效,但只有仔细的基准测试才会告诉您,因为现代处理器的分支预测将最小化成本,如果这些测试将91
值存储到本地阵列是一个小额外成本.
顺便问一下,你确定col < 92
吗?你的循环对待91
列,但你写的,只有90
在的92
列是整数.
同样,我首先会寻找一种从MySQL中提取值作为整数的方法.