gpt4 book ai didi

java - Java中方便快捷的3D vector 数学

转载 作者:行者123 更新时间:2023-12-05 07:57:37 26 4
gpt4 key购买 nike

总的来说,与 C++ 相比,我更喜欢用 Java 编程,主要是因为库的链接要容易得多(没有“依赖 hell ”),而且因为有很多开箱即用的功能强大的包。我也喜欢 jMonkey 和 Processing 等 Java 工具。

但是,我经常做一些物理方面的事情,我需要用 3D vector 进行快速数学运算。而且我没有找到任何方便的方法来在 Java 中实现既高效又可读(C++ 构造,如宏、重载运算符、结构和通过引用传递变量是用于此目的的非常有用的工具)。

例如中心力场中质量粒子的蛙跳积分器。在 C++ 中,我可以做这样的事情(使用 float3 类型的重载运算符):

float   ir2      =  1.0f/dot(vec_pos,vec_pos);
float ir = sqrt(ir2);
float3 vec_G = -vec_pos / (ir2*ir);
vec_v += vec_G*dt;
vec_pos += vec_v*dt;

Java 中的可读代码如下所示:

float   ir2      =  1.0f/vec_pos.mag2();
float ir = sqrt(ir2);
float3 vec_G = vec_pos.mult( -ir2*ir);
vec_v .addLocal( vec_G.multLocal( dt ) );
vec_pos .addLocal( vec_v.mult ( dt ) );

这对性能来说不是很好,因为它将新对象分配为临时变量,其中“本地”方法是不可能使用的。我可以通过为 fused-multiply-add 定义新方法来优化它,例如:

float   ir2      =  1.0f/vec_pos.mag2();
float ir = sqrt(ir2);
float3 vec_G = vec_pos.mult( -ir2*ir);
vec_v .addLocal_vec_times_scalar( vec_G, dt );
vec_pos .addLocal_vec_times_scalar( vec_v, dt );

但是用 float3 vector 为所有可能的算术运算组合定义专门的方法不是很方便……比如:

  float3.addLocal_vec1_times_vec2_times_scalar() 

另一种避免动态分配临时对象的策略是将临时变量定义为一些静态全局变量(这不是很好的编码风格)或封闭类的属性,例如:

class asteroide{
// state variables
float3 vec_pos;
float3 vec_v;
// temporary variables
float3 vec_G,vec_dpos;

void update_leapfrog(float dt){
float ir2 = 1.0f/vec_pos.mag2();
float ir = sqrt(ir2);
vec_G .set_mult( vec_pos, -ir2*ir );
vec_v .addLocal( vec_G.multLocal( dt ) );
dpos .set_mult( vec_v, dt );
vec_pos .addLocal( dpos );
}
}

在这两种情况下,解引用指向此对象的指针都会产生性能成本。它还使小行星对象消耗更多内存

还有调用对象方法的性能损失(即使我试图使它们成为“最终的”和“静态的”以便 JIT 可以有效地内联它们)。根据我的测试,使用 float3.mult() 比仅乘以 3 float 慢 2-3 倍。

所以我经常只使用 float 来编写复杂的 vector 代数计算,以避免这种性能损失。 :((((但是它根本不可读。以这种方式进行刚体动力学和空气动力学计算是很痛苦的。它和 40 年前的 Fortran77 程序一样糟糕!!!! (出于好奇,请参阅 Xfoil 的代码 http://web.mit.edu/drela/Public/web/xfoil/)

对于在 Java 中进行 vector 数学运算,您推荐什么策略既高效又方便(~可读)?

最佳答案

也许不是真正的答案,但评论时间太长了。

您是如何衡量绩效的?所有的优化都需要一段时间;如果您的测量时间少于几秒钟,那么就算了吧。

理论上,JIT 应该能够优化掉不必要的分配。

关于丑陋:当然,像 addLocal_vec_times_scalar 这样的名字一定是丑陋的。像 addProduct 这样的东西就可以了。

There is also performance penalty for calling object methods (even if I try to make them "final" and "static" so JIT can inline them effectively )

这不是必需的,因为 JIT 可以查看该方法是否在某处被覆盖。

What strategy you recommend for doing vector math in Java both performance efficient and convenient (~readable)?

不要试图让它看起来像 C。定义一些方法,如融合乘法并忽略罕见情况。如果您使用像 float3.addLocal_vec1_times_vec2_times_scalar 这样的名称,它一定很丑陋。怎么了

 vec1.addProduct(vec2, vec3, someScalar)

关于java - Java中方便快捷的3D vector 数学,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26390570/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com