Java代码执行时间问题
在我对网络扩散的研究中,我有以下代码为顶点建模一个轻量级框架。最初的原型来自python框架,我将其翻译成Java。我遇到的问题是,虽然此代码运行速度比其python版本快得多,最多可运行10000个顶点,但对于更多的顶点(100000+),它会停止运行。事实上,python版本在1.2分钟内执行,而java构建即使在执行7分钟后也没有返回。我不知道为什么相同的代码会在更多的顶点上崩溃,我需要关于修复代码的帮助Java代码执行时间问题,java,python,performance,collections,Java,Python,Performance,Collections,在我对网络扩散的研究中,我有以下代码为顶点建模一个轻量级框架。最初的原型来自python框架,我将其翻译成Java。我遇到的问题是,虽然此代码运行速度比其python版本快得多,最多可运行10000个顶点,但对于更多的顶点(100000+),它会停止运行。事实上,python版本在1.2分钟内执行,而java构建即使在执行7分钟后也没有返回。我不知道为什么相同的代码会在更多的顶点上崩溃,我需要关于修复代码的帮助 import java.util.*; public class Vertex {
import java.util.*;
public class Vertex
{
private int id;
private HashMap<Integer, Double> connectedTo;
private int status;
public Vertex(int key)
{
this.id = key;
this.connectedTo = new HashMap<Integer, Double>();
this.status = 0;
}
public void addNeighbour(int nbr, double weight)
{
this.connectedTo.put(nbr, weight);
}
public int getId()
{
return this.id;
}
public double getWeight(int nbr)
{
return this.connectedTo.get(nbr);
}
public int getStatus()
{
return this.status;
}
public Set<Integer> getConnections()
{
return this.connectedTo.keySet();
}
//testing the class
public static void main(String[] args)
{
int noOfVertices = 100000;
Vertex[] vertexList = new Vertex[noOfVertices];
for (int i = 0; i < noOfVertices; i++) {
vertexList[i] = new Vertex(i);
}
for (Vertex v : vertexList) {
int degree = (int)(500*Math.random()); //random choice of degree
int neighbourCount = 0; // count number of neighbours built up
while (neighbourCount <= degree) {
int nbr = (int) (noOfVertices * Math.random()); // randomly choose a neighbour
double weight = Math.random(); // randomly assign a weight for the relationship
v.addNeighbour(nbr, weight);
neighbourCount++;
}
}
}
}
import java.util.*;
公共类顶点
{
私有int-id;
连接到的私有HashMap;
私人身份;
公共顶点(int键)
{
this.id=键;
this.connectedTo=newhashmap();
这个状态=0;
}
公共空间(内部nbr,双倍重量)
{
此连接到put(nbr,重量);
}
公共int getId()
{
返回此.id;
}
公共双倍重量(内部编号)
{
返回此.connectedTo.get(nbr);
}
public int getStatus()
{
返回此状态;
}
公共集getConnections()
{
返回此.connectedTo.keySet();
}
//测试课程
公共静态void main(字符串[]args)
{
int noOfVertices=100000;
顶点[]顶点列表=新顶点[noOfVertices];
for(int i=0;i 虽然(neighbourCount这是一个非常有趣的问题,我相信我也学到了一些新的东西。我尝试用不同的方法优化代码,比如使用并行流以及使用ThreadLocalRandom
,这可能比Random
快三倍。然而,我最终发现了主要的瓶颈:分配给JVM的内存
由于要向映射添加的元素太多(最坏的情况是500000个,顶点100000个),因此需要大量内存(堆空间)。如果允许JVM动态分配内存,那么程序将需要很长时间才能执行。我解决这一问题的方法是将内存预分配给JVM(特别是3 GB)将-Xms3G
作为VM参数应用于程序的运行配置,该配置可以在IDE中或通过终端完成
我还对您的代码进行了一些优化,我将在下面发布(我只需几秒钟即可完成):
import java.util.*;
导入java.util.concurrent.*;
导入java.util.stream.*;
公开课考试{
私有静态final ThreadLocalRandom=ThreadLocalRandom.current();
公共静态void main(字符串[]args){
内部无弹性=100_000;
顶点[]顶点列表=新顶点[noOfVertices];
IntStream.range(0,noOfVertices).parallel().forEachOrdered(i->{
顶点列表[i]=新顶点(i);
int度=(int)(500*RANDOM.nextDouble());//度的随机选择
对于(int j=0;j),我目前正在研究这个问题,并将很快发布一些优化的代码!如果不进行分析,很难判断,实际上几乎可以在任何地方。不过,简单地说一下:看看java.util.Random
类,它有一个nextInt(bound)
方法(这不太可能是一个相当大的加速,但仍然如此)找到解决方案并把它发布到下面!一个相当优雅的解决方案,我没有考虑过。感谢你的努力。@ BuZAKU不受欢迎,我真的不知道分配堆空间可以在性能中发挥作用,但我很高兴你的问题是固定的!
import random
class Vertex:
def __init__(self, key):
self.id = key
self.connectedTo = {}
def addNeighbor(self, nbr, weight=0):
self.connectedTo[nbr] = weight
def __str__(self):
return str(self.id) + ' connectedTo: ' \
+ str([x.id for x in self.connectedTo])
def getConnections(self):
return self.connectedTo.keys()
def getId(self):
return self.id
def getWeight(self, nbr):
return self.connectedTo[nbr]
if __name__ == '__main__':
numberOfVertices = 100000
vertexList = [Vertex(i) for i in range(numberOfVertices)] # list of vertices
for vertex in vertexList:
degree = 500*random.random()
# build up neighbors one by one
neighbourCount = 0
while neighbourCount <= degree:
neighbour = random.choice(range(numberOfVertices))
weight = random.random() # random choice of weight
vertex.addNeighbor(neighbour, weight)
neighbourCount = neighbourCount + 1
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.*;
public class Test {
private static final ThreadLocalRandom RANDOM = ThreadLocalRandom.current();
public static void main(String[] args) {
int noOfVertices = 100_000;
Vertex[] vertexList = new Vertex[noOfVertices];
IntStream.range(0, noOfVertices).parallel().forEachOrdered(i -> {
vertexList[i] = new Vertex(i);
int degree = (int) (500 * RANDOM.nextDouble()); // random choice of degree
for (int j = 0; j <= degree; j++) {
int nbr = (int) (noOfVertices * RANDOM.nextDouble()); // randomly choose a neighbor
vertexList[i].addNeighbour(nbr, RANDOM.nextDouble());
}
});
}
}
class Vertex {
private int id;
private Map<Integer, Double> connectedTo;
private int status;
public Vertex(int id) {
this.id = id;
this.connectedTo = new HashMap<>(500);
}
public void addNeighbour(int nbr, double weight) {
this.connectedTo.put(nbr, weight);
}
public int getId() {
return this.id;
}
public double getWeight(int nbr) {
return this.connectedTo.get(nbr);
}
public int getStatus() {
return this.status;
}
public Set<Integer> getConnections() {
return this.connectedTo.keySet();
}
}