为什么这个Java应用程序在Mac而不是PC上运行缓慢? [英] Why does this Java app run slow on Mac and not PC?
问题描述
我使用Java创建了一个应用程序,它在Windows平台上运行顺畅。但是,当我在Macbook Pro Retina 15'上使用4960HQ进行测试时,显示的帧速率要低得多。
I have created an application using Java and it runs smoothly on the Windows platform. However, when it is tested on my Macbook Pro Retina 15' with 4960HQ, the displayed frame rates are considerably lower.
我编写了程序以恒定运行动画60fps和控制台显示在Mac和Windows上都绘制了60fps。但是,Mac上的程序似乎以6-8fps的速度运行。
I have coded the program to run animations at a constant 60fps and the console shows that 60fps is being drawn on both Mac and Windows. However, the program on Mac looks like it is running at 6-8fps.
是否有适合Mac的特殊编码方法?或者java根本没有针对Mac OSX进行优化?
Is there special coding methodology tailored for Mac? Or is java simply not optimized for Mac OSX?
代码的最小工作样本:
long framerate = 1000 / 60;
// time the frame began
long frameStart;
// number of frames counted this second
long frameCount = 0;
// time elapsed during one frame
long elapsedTime;
// accumulates elapsed time over multiple frames
long totalElapsedTime = 0;
// the actual calculated framerate reported
while(true){
frameStart = System.currentTimeMillis();
world.moveBG(3);
// calculate the time it took to render the frame
elapsedTime = System.currentTimeMillis() - frameStart;
// sync the framerate
try {
// make sure framerate milliseconds have passed this frame
if (elapsedTime < framerate) {
Thread.sleep(framerate - elapsedTime);
} else {
// don't starve the garbage collector
Thread.sleep(5);
}
} catch (InterruptedException e) {
break;
}
++frameCount;
totalElapsedTime += (System.currentTimeMillis() - frameStart);
if (totalElapsedTime > 1000) {
reportedFramerate = (long) ((double) frameCount
/ (double) totalElapsedTime * 1000.0);
// show the framerate in the applet status window
System.out.println("fps: " + reportedFramerate);
// repaint();
frameCount = 0;
totalElapsedTime = 0;
}
}
这段代码处理控制fps,它是现在设置为60fps。 world.moveBG(3)
以每帧3个像素的速度在屏幕上移动和图像(这不应该是性能密集型的,因为它是一个小图像)。 Mac以明显的10fps运行,窗口平滑60.两台机器上的控制台显示正在绘制60fps。
This bit of code handles controlling the fps, it is set to 60fps right now. the world.moveBG(3)
moves and image across the screen at speed of 3 pixels per frame (which should not be performance intensive as it is a small image). Mac runs this at an apparent 10fps and windows at a smooth 60. The console on both machines display that 60fps is being drawn.
澄清一下,它不是'在Mac的屏幕上图像移动速度比Windows快,这是Mac上的运动非常不稳定
推荐答案
下一个代码启动执行程序并安排任务以完成帧速率。
在Windows上运行3秒,我的最后一条跟踪指示了179个任务,因此几乎每秒需要执行60个任务。
The next code starts an executor and schedule the tasks to acomplish your framerate. Running this on Windows for 3 seconds the last trace I have indicates 179 tasks so almost the 60 tasks per second that you want to acomplish.
试试这段代码让我知道是否可以改善你的表现:
Try this code and let me know if improves your performance:
package com.nosolojava.test;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.logging.Logger;
public class FrameRateExecutor {
private final Logger logger = Logger.getLogger(this.getClass().getCanonicalName());
final static long framerate = 1000 / 60;
// number of frames counted this second
AtomicInteger frameCount = new AtomicInteger(0);
ScheduledExecutorService executor;
private volatile AtomicBoolean running = new AtomicBoolean(false);
class Task implements Runnable {
private final long lastTaskTimeStamp;
public Task() {
super();
//get creation time so we can calculate delay after
this.lastTaskTimeStamp = System.currentTimeMillis();
}
public void run() {
// TODO implement logic
logger.log(
Level.INFO,
String.format("Do something, framecount: %02d %d", frameCount.addAndGet(1),
System.currentTimeMillis()));
//calculate when to execute next task and submit
long currentTime = System.currentTimeMillis();
long elapsed = currentTime - lastTaskTimeStamp;
long delay = (framerate - elapsed) +framerate;
logger.log(Level.INFO, String.format("elapsed %04d delay %04d", elapsed, delay));
//check finish condition
if (running.get()) {
executor.schedule(new Task(), delay, TimeUnit.MILLISECONDS);
}
}
};
public void stop() {
running.set(false);
executor.shutdown();
try {
executor.awaitTermination(3, TimeUnit.SECONDS);
} catch (InterruptedException e) {
logger.log(Level.SEVERE, "Error stopping executor", e);
}
}
public void start() {
//check if is already up
if (this.running.compareAndSet(false, true)) {
//init scheduled executor
executor = new ScheduledThreadPoolExecutor(1);
//start first task
executor.execute(new Task());
}
}
public static void main(String[] args) throws InterruptedException {
FrameRateExecutor frameExecutor = new FrameRateExecutor();
frameExecutor.start();
Thread.sleep(3000);
frameExecutor.stop();
}
}
这篇关于为什么这个Java应用程序在Mac而不是PC上运行缓慢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!