我的任务是优化使用Cognos SDK开发的应用程序,该应用程序查询内容存储库中的所有软件包,然后将它们写入SQL数据库。该应用程序是由我的前任以该角色编写的,并且做了一些有趣的事情……它有几个手动的system.GC调用被我禁用,以及一个循环中的System.wait(2000)。目前,它可以在服务器体系结构上更快地运行,但是如果尝试在普通客户端上运行它,则由于堆错误而崩溃。如此深入研究,我发现其中有成千上万的琴弦。显而易见的答案是更改为StringBuilder,但是如果我必须在其中使用很多“ toString”,是否真的可以节省任何内存?从理论上讲,每个字符串运算符都应该有一个方法,但是我有点不愿意弄乱应用程序上的某些逻辑,因此我不得不专门研究如何做每一个。很抱歉以前是否有人问过这个问题,但是环顾了一个小时之后,我找不到了。
(小:整个方法的认知复杂度为174,但是其中相当一部分是cognos特有的,我不知道从哪里开始减少。)
这是我所做的更改的一个示例(此循环在〜450000行输入上运行了几次)。另外,我在for循环之前不久将“ express”更改为初始值为“”的StringBuilder,这是其中的一部分:
if (element.hasAttribute("expression") && element.getAttribute("expression") != "") {
formula = element.getAttribute("expression");
for (int k = 0; k < formula.length(); k++) {
if (formula.charAt(k) == '<')
exSearch++;
if (exSearch == 0)
express.append(formula.charAt(k));
if (formula.charAt(k) == '>')
exSearch--;
}
express.replace(0, express.length(),express.toString().replaceAll("\\s", ""));
express.replace(0, express.length(),express.toString().replaceAll(">", "<"));
express.replace(0, express.length(),express.toString().replaceAll("<", ">"));
express.replace(0, express.length(),express.toString().replaceAll("'", "'"));
express.replace(0, express.length(),express.toString().replaceAll("&", "&"));
}
if (express.length() > 1000) {
express.replace(0, express.length(),express.toString().substring(0, 995) + "..." );
}
table = "CALCULATION";
tableLoc = "CALCULATION";
inBrackets = false;
if (express.indexOf("[")== 0) {
String[] temp = express.toString().split("].");
if (temp.length > 1 && temp[temp.length - 1].length() > 1) {
table = temp[temp.length - 2].substring(1);
tableLoc = temp[temp.length - 1].substring(1, temp[temp.length - 1].length() - 1);
}
}
原始:
if (element.hasAttribute("expression") && element.getAttribute("expression") != "") {
formula = element.getAttribute("expression");
for (int k = 0; k < formula.length(); k++) {
if (formula.charAt(k) == '<')
exSearch++;
if (exSearch == 0)
express += formula.charAt(k);
if (formula.charAt(k) == '>')
exSearch--;
}
express = express.replaceAll("\\s", "");
express = express.replaceAll(">", "<");
express = express.replaceAll("<", ">");
express = express.replaceAll("'", "'");
express = express.replaceAll("&", "&");
}
if (express.length() > 1000) {
express = express.substring(0, 995) + "...";
}
table = "CALCULATION";
tableLoc = "CALCULATION";
inBrackets = false;
if (express.startsWith("[")) {
String[] temp = express.split("].");
if (temp.length > 1 && temp[temp.length - 1].length() > 1) {
table = temp[temp.length - 2].substring(1);
tableLoc = temp[temp.length - 1].substring(1, temp[temp.length - 1].length() - 1);
}
}
答案 0 :(得分:0)
是的,用StringBuilder替换字符串算法将对内存和性能产生影响。但是您的新代码仍然对所有toString()。replaceAll和toString()。split和toString()。substring()调用进行了大量的字符串运算。摆脱所有这些。它们都是昂贵且完全不必要的。
不要对字符串执行任何操作,而是在单个StringBuilder实例上全部进行操作。
对于内存不足,大多数字符串都是垃圾回收的,因此尚不清楚这是否可以解决内存问题。但这肯定会改善。
答案 1 :(得分:0)
请献上上帝的爱
express = express.replaceAll("\\s", "");
express = express.replaceAll(">", "<");
express = express.replaceAll("<", ">");
express = express.replaceAll("'", "'");
express = express.replaceAll("&", "&");
进入
express = express.replace("\\s", "").replace(">", "<").replace("<", ">").replace("'", "'").replace("&", "&")