java调用python(用于实现空间三点定位一点) 通过Runtime.getRuntime().exec()方式的加速

因项目需求要实现三点 + 一点空间坐标定位,发现用python现有的solve方法会很方便,于是乎产生了spring调用python的想法,但因执行频率过高导致效率一直低下,于是有了加速的想法。

  1. 在优化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代码更为方便最终还是没采用该方案,在此记录。
附上运行效果截图:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值