c比java运行快的原因_为什么这段代码在java中比在C和C#中更快?

我正在做一个简单的家庭作业,我必须在C中开发一个软件,找到100个之间的两个最近的点.

当我完成时,我很好奇地看到需要多少时间才能运行它并获得更多积分并启用完整的VC优化.我尝试了10000,花了大约8~9秒.然后我很想知道C#和Java花多少时间做同样的事情.正如预期的那样,C#需要更长的时间,9~10秒;然而,Java只花了大约400毫秒!为什么会这样?!

这是我在C,C#和Java中的代码:

C:

#include

#include

#include

#include

long perfFrequency = 0;

typedef struct

{

double X;

double Y;

} Point;

double distance(Point p1, Point p2)

{

return sqrt(pow(p1.X - p2.X, 2) + pow(p1.Y - p2.Y, 2));

}

double smallerDistance(Point *points, int size, Point *smallerA, Point *smallerB)

{

int i, j;

double smaller = distance(points[0], points[1]);

for (i = 0; i < size; i++)

{

for (j = i + 1; j < size; j++)

{

double dist = distance(points[i], points[j]);

if (dist < smaller)

{

smaller= dist;

*smallerA = points[i];

*smallerB = points[j];

}

}

}

return smaller;

}

void main()

{

// read size and points from file.

int size;

Point *points= (Point *)malloc(size * sizeof(Point));

// just to make sure everything is ready before the benchmark begins

system("pause");

Point smallerA, smallerB;

if (!QueryPerformanceFrequency((LARGE_INTEGER *)&perfFrequency))

printf("Couldn't query performance frequency.");

long long start, end;

double smaller;

QueryPerformanceCounter((LARGE_INTEGER *)&start);

smaller= smallerDistance(points, size, &smallerA, &smallerB);

QueryPerformanceCounter((LARGE_INTEGER *)&end);

printf("The smaller distance is: %lf. The coordinates of the most close points are: (%lf, %lf) and (%lf, %lf). Time taken: %lfms\n",

smaller, smallerA.X, smallerA.Y, smallerB.X, smallerB.Y, (end - start) * 1000.0 / perfFrequency);

}

C#:

using System;

using System.IO;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Diagnostics;

namespace StructuredTest

{

struct Point

{

public double X;

public double Y;

}

class Program

{

static double Distance(Point p1, Point p2)

{

return Math.Sqrt(Math.Pow(p1.X - p2.X, 2) + Math.Pow(p1.Y - p2.Y, 2));

}

static double SmallerDistance(Point[] points, int size, out Point smallerA, out Point smallerB)

{

int i, j;

double smaller = Distance(points[0], points[1]);

smallerA = default(Point);

smallerB = default(Point);

for (i = 0; i < size; i++)

{

for (j = i + 1; j < size; j++)

{

double dist = Distance(points[i], points[j]);

if (dist < smaller)

{

smaller = dist;

smallerA = points[i];

smallerB = points[j];

}

}

}

return smaller;

}

static void Main(string[] args)

{

// read size and points from file

int size = int.Parse(file[0]);

Point[] points= new Point[size];

// make sure everything is ready

Console.WriteLine("Press any key to continue...");

Console.ReadKey(true);

Point smallerA, smallerB;

double smaller;

Stopwatch sw = new Stopwatch();

sw.Restart();

smaller = SmallerDistance(points, size, out smallerA, out smallerB);

sw.Stop();

Console.WriteLine($"The smaller distance is: {smaller}. The coordinates of the most close points are: ({smallerA.X}, {smallerA.Y}) and " +

$"({smallerB.X}, {smallerB.Y}). Time taken: {sw.ElapsedMilliseconds}ms.");

}

}

}

Java的:

package structuredtest;

import java.io.IOException;

import java.nio.charset.Charset;

import java.nio.file.Files;

import java.nio.file.Paths;

import java.util.List;

class Point {

public Point(double X, double Y) {

this.X = X;

this.Y = Y;

}

double X;

double Y;

}

class Result {

double distance;

Point p1;

Point p2;

}

public class StructuredTest {

static double distance(Point p1, Point p2) {

return Math.sqrt(Math.pow(p1.X - p2.X, 2) + Math.pow(p1.Y - p2.Y, 2));

}

static Result smallerDistance(Point[] points, int size) {

int i, j;

double smaller = distance(points[0], points[1]);

Result r = new Result();

for (i = 0; i < size; i++) {

for (j = i + 1; j < size; j++) {

double dist = distance(points[i], points[j]);

if (dist < smaller) {

smaller = dist;

r.p1 = points[i];

r.p2 = points[j];

}

}

}

r.distance = smaller;

return r;

}

public static void main(String[] args) throws IOException {

// read size and points from file

int size = Integer.parseInt(file[0]);

Point[] points = new Point[size];

// make sure everything is ready

System.out.println("Press any key to continue...");

System.in.read();

double start = System.nanoTime(), end;

Result r = smallerDistance(points, size);

end = System.nanoTime();

System.out.println("The smaller distance is: " + r.distance + ". The most close points are: ("

+ r.p1.X + "," + r.p1.Y + ") and " + r.p2.X + "," + r.p2.Y + "). Time taken: " + (end - start) / 1000000 + "ms.");

}

}

如果java以小幅度击败C和C#我不会感到惊讶,但速度快20倍?!

该文件采用以下格式:

3 // number of points in the file. Note that there no comments in the actual file

(3.7098722472288, 4.49056397953787) // point (X,Y)

(8.90232811621332, 9.67982769279173)

(5.68254334818822, 1.71918922506136)

(6.22585901842366, 9.51660500242835)

有趣的是:首先,我之前提到的10000点的文件,我用来进行基准测试,实际上只是100个随机点的另一个文件的100倍复制粘贴.像这样:

(Point 1)

(Point 2)

(Point 3)

(Point 1)

(Point 2)

(Point 3)

我认为不需要生成10000个随机点,因为无论如何代码必须遍历所有数字,它会产生很小的差异(只有更多的任务).但后来我决定生成10000个随机点来看看它们会如何反应:C和C#在大约相同的时间内仍然运行(增加约50ms);另一方面,Java增加了~500ms.

此外,我认为值得注意的是,在NetBeans中运行时,java大约需要11秒(即使在“运行”模式下,而不是“调试”).

我也尝试编译为C而不是C,但它没有任何区别.

我正在使用VS 2015进行C和C#.

这些是每种语言的设置:

C:

x64

Optimization: Maximize Speed (/O2)

Intrinsic Functions: Yes (/Oi)

Favor Size or Speed: Favor fast code (/Ot)

Enable Fiber-Safe Optimizations: Yes (/GT)

Security Check: Disable Security Check (/GS-)

Floating point model: Fast (/fp:fast)

Everything else: default

C#:

x64

Release Mode

Optimize Code: Enabled

Check for arithmetic overflow: Disabled

.NET 4.5.2

Java的:

JRE/JDK 1.8

Default settings (if there are any)

编辑:

好的,我按照建议重新做了测试:

首先,我在C和C#中使用了Result类/结构.我在java中使用它而不是在C/C++#中使用它的原因是因为java无法通过引用传递.

其次,我现在在main()函数中重复测试.

并感谢@Tony D捕获该错误!

标签:c-3,java,c,c-2,performance

来源: https://codeday.me/bug/20190722/1503885.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值