Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/397.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 奇怪的JVM与.NET CLR性能差异(短期对象和虚拟调用)_Java_.net_Garbage Collection_Jvm_Clr - Fatal编程技术网

Java 奇怪的JVM与.NET CLR性能差异(短期对象和虚拟调用)

Java 奇怪的JVM与.NET CLR性能差异(短期对象和虚拟调用),java,.net,garbage-collection,jvm,clr,Java,.net,Garbage Collection,Jvm,Clr,我正在用虚拟方法测试装箱+调用+丢弃大量短期对象的性能 这是我的C#代码: 使用系统; 使用System.Collections.Generic; 使用System.Linq; 使用系统文本; 使用System.Threading.Tasks; 命名空间BoxingTest { 公共抽象类BoxedVal { 公开摘要BoxedVal Add(BoxedVal其他); 公共摘要bool LessThan(BoxedVal其他); 公共摘要bool GreaterThan(BoxedVal其他);

我正在用虚拟方法测试装箱+调用+丢弃大量短期对象的性能

这是我的C#代码:
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
命名空间BoxingTest
{
公共抽象类BoxedVal
{
公开摘要BoxedVal Add(BoxedVal其他);
公共摘要bool LessThan(BoxedVal其他);
公共摘要bool GreaterThan(BoxedVal其他);
}
公共级拳击力量:拳击
{
公共价值观;
公共力(int值)
{
价值=价值;
}
公共覆盖BoxedVal添加(BoxedVal其他)
{
拳击力i=其他拳击力;
返回新的力(值+i.Value);
}
公共覆盖bool LessThan(BoxedVal其他)
{
拳击力i=其他拳击力;
返回值i.值;
}
}
班级计划
{
专用静态整数Fib(整数nn)
{
BoxedVal一号=新的Boxed力(1);
BoxedVal a=一个;
BoxedVal b=一个;
BoxedVal n=新的盒力(nn);
BoxedVal千=新的BoxedDint(1000);
对于(BoxedVal i=新的BoxedInt(2);i.LessThan(n);i=i.添加(一))
{
BoxedVal c=a.添加(b);
a=b;
b=c;
如果(b.大于(千))
{
a=一;
b=一个;
}
}
返回值(b为力)。值;
}
静态void Main(字符串[]参数)
{
整数倍=5;
int n=20000000;
int-total=0;
for(int i=0;i
和Java中的相同代码:
package-boxingtest;
抽象类BoxedVal
{
公开摘要BoxedVal Add(BoxedVal其他);
公共抽象布尔LessThan(BoxedVal其他);
公共抽象布尔值大于(BoxedVal其他);
}
类BoxedInt扩展BoxedVal
{
公共价值观;
公共力(int值)
{
价值=价值;
}
@凌驾
公用箱包添加(箱包其他)
{
拳击力i=(拳击力)其他;
返回新的力(值+i.Value);
}
@凌驾
公共布尔LessThan(BoxedVal其他)
{
拳击力i=(拳击力)其他;
返回值i.值;
}
}
公共类BoxingTest{
专用静态整数Fib(整数nn)
{
BoxedVal一号=新的Boxed力(1);
BoxedVal a=一个;
BoxedVal b=一个;
BoxedVal n=新的盒力(nn);
BoxedVal千=新的BoxedDint(1000);
对于(BoxedVal i=新的BoxedInt(2);i.LessThan(n);i=i.添加(一))
{
BoxedVal c=a.添加(b);
a=b;
b=c;
如果(b.大于(千))
{
a=一;
b=一个;
}
}
返回((力)b)值;
}
公共静态void main(字符串[]args){
整数倍=5;
int n=20000000;
长总计=0;

对于(inti=0;i,在我的环境中,Java1.8.0.25的速度大约是.NET4.5.1(x64和x64)的三倍。 将“as”表达式更改为标准转换就更接近了

BoxedInt i = other as BoxedInt;

并添加一些结构,如

int Value;
int[] Dummy;

public BoxedInt(int value)
{
    Value = value;
    Dummy = new int[10];
}
两者都使Java的速度比.NET慢8倍
这种微基准测试显示了有趣的结果,但在许多方面都不可行。

在我的环境中,Java 1.8.0.25的速度大约是.NET 4.5.1(x64和x64)的三倍。 将“as”表达式更改为标准转换就更接近了

BoxedInt i = other as BoxedInt;

并添加一些结构,如

int Value;
int[] Dummy;

public BoxedInt(int value)
{
    Value = value;
    Dummy = new int[10];
}
两者都使Java的速度比.NET慢8倍
这种微基准测试显示了有趣的结果,但在许多方面都不可行。

有很多方法可以解决这种情况。在不更改代码的情况下,启用“服务器”垃圾收集器应该可以缩小这一差距:


另一种方法是在C#代码中小心地使用值类型而不是引用类型,以避免完全分配,即使您正在处理许多值的“实例”。这并不总是正确的方法,但对于某些类型的问题(尤其是上面所示的情况),值类型可能导致.NET代码的执行速度比等效Java代码快很多倍。

有很多方法可以解决这种情况。在不更改代码的情况下,启用“服务器”垃圾回收器应该可以缩小这一差距:


另一种方法是在C#代码中小心地使用值类型而不是引用类型,以避免完全分配,即使您正在处理许多值的“实例”。这并不总是正确的方法,但对于某些类型的问题(尤其是上面所示的情况),值类型可能导致.NET代码的执行速度比等效Java代码快很多倍。

在这种情况下,使用服务器GC不会发生任何更改,因为只有一个线程正在运行。值类型也是错误的选择。 值类型比or值慢约40%
int Value;
int[] Dummy;

public BoxedInt(int value)
{
    Value = value;
    Dummy = new int[10];
}