为什么这个Java应用程序在Mac而不是PC上运行缓慢? [英] Why does this Java app run slow on Mac and not PC?

查看:104
本文介绍了为什么这个Java应用程序在Mac而不是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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆