因项目需求要实现三点 + 一点空间坐标定位,发现用python现有的solve方法会很方便,于是乎产生了spring调用python的想法,但因执行频率过高导致效率一直低下,于是有了加速的想法。
- 在优化python的执行代码。简单来说用更快的库方法,更简短的处理方式。如:
def solve_eq(ae, be, ce, de):
a = point(350, -75, 826)
b = point(1160, -75, 826)
c = point(1170, 685, 826)
d = point(355, 685, 826)
xe, ye, ze = sym.symbols('xe ye ze')
eqs = []
if ae:
eqs.append(Eq((xe - a.x) ** 2 + (ye - a.y) ** 2 + (ze - a.z) ** 2 - ae ** 2, 0))
if be:
eqs.append(Eq((xe - b.x) ** 2 + (ye - b.y) ** 2 + (ze - b.z) ** 2 - be ** 2, 0))
if ce:
eqs.append(Eq((xe - c.x) ** 2 + (ye - c.y) ** 2 + (ze - c.z) ** 2 - ce ** 2, 0))
if de:
eqs.append(Eq((xe - d.x) ** 2 + (ye - d.y) ** 2 + (ze - d.z) ** 2 - de ** 2, 0))
solution = nsolve(eqs, [xe, ye, ze], [400, 200, 120], verify=False)
# solution = solve(eqs, [xe, ye, ze])
result = []
for j in solution:
result.append(j)
return result
采用nsolve而非solve。
2.python代码采用控制台输入输出方式,而非一次性输入方式,减少进程创建次数。如:
if __name__ == '__main__':
ae, be, ce, de = 0, 0, 0, 0
dis_list = []
while True:
args = sys.stdin.readline()
start = time.time()
dis_list = args.split(sep=';')
for i in dis_list:
ae, be, ce, de, ms = i.split(sep=' ')
all = filtration(float(ae), float(be), float(ce), float(de))
if len(all) != 0:
result = str('%.2f' % all[0] + " " + '%.2f' % all[1] + " " + '%.2f' % all[2] + " " + ms +"\n")
print(result, flush=True, file=sys.stdout, end='')
# print(time.time() - start)
3.java调用方面因采用控制台输入输出方式,单次控制输入后再读取输出会因为运行阻塞而非常慢。于是采用多线程处理输入和输出和控制台进程即一主两子线程方式进行加速。如:
public static void main(String[] args) throws IOException {
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec("python -u D:\\testxmuz\\src\\main\\java\\com\\analyse\\pointcalc.py");
BufferedWriter outputStream = process.outputWriter();
BufferedReader inputStream = process.inputReader();
AtomicInteger outTimes = new AtomicInteger();
int times = 0;
new Thread(() -> {
try {
while (true) {
outTimes.set(outTimes.get() + 1);
outputStream.write("920.09 967.3 894.74 835.87 " + new Date().getTime() + '\n');
outputStream.flush();
Thread.sleep(10);
}
} catch (Exception e) {
}
}).start();
new Thread(() -> {
String s = "";
while (true) {
try {
long start = new Date().getTime();
s = inputStream.readLine();
if (!s.isEmpty()) {
outTimes.set(outTimes.get()-1);
System.out.println("read : " + outTimes.get() + " xx :" + s);
System.out.println("time : " + (new Date().getTime() - start));
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}).start();
while (true) {
}
}
在这些操作下,原本单次运行加上读取本一次需要耗时300-500ms的速度,加速到了10-18ms,满足需求。但发现直接写java代码更为方便最终还是没采用该方案,在此记录。
附上运行效果截图: