【问题标题】:Why this code have performance issue even without synchronized keyword?为什么即使没有同步关键字,这段代码也会出现性能问题?
【发布时间】:2016-07-11 12:06:46
【问题描述】:

为什么下面的代码有性能问题,相机的帧不平滑。

public class VideoCaptureAndroid implements PreviewCallback, Callback{
  private Integer deviceRotation = Integer.MAX_VALUE;

  public VideoCaptureAndroid(Context context, int id, long native_capturer) {
    deviceRotationNotifier = new OrientationEventListener(context, SensorManager.SENSOR_DELAY_NORMAL) {
      public void onOrientationChanged(int orientation) {
        if (orientation == ORIENTATION_UNKNOWN) {
          Log.d(TAG, "The device rotation angle is unknown.");
          return;
        }

        synchronized(deviceRotation) {
          if (deviceRotation != orientation) {
            deviceRotation = orientation;
          }
        }
      }
    };

    Exchanger<Handler> handlerExchanger = new Exchanger<Handler>();
    cameraThread = new CameraThread(handlerExchanger);
    cameraThread.start();
  }

  public synchronized void onPreviewFrame(byte[] data, Camera callbackCamera) {

    int frameRotation = info.orientation;
    if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
       frameRotation = (info.orientation - deviceRotation + 360) % 360;
    } else if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
       frameRotation = (info.orientation + deviceRotation) % 360;
    }
    onFrame(data, data.length, native_capturer, frameRotation);
    camera.addCallbackBuffer(data);
  }

  }

好像我注释掉下面的代码,框架很流畅,没有性能问题。但是我没有在onPreviewFrame中使用synchronized来访问deviceRotation,为什么会受到onOrientationChanged的影响?

if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
   frameRotation = (info.orientation - deviceRotation + 360) % 360;
} else if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
   frameRotation = (info.orientation + deviceRotation) % 360;
}

【问题讨论】:

  • 你试过Code Review吗?
  • @JosephWood 不过,他并不是在寻找性能改进,而是在问为什么特定的 sn-p 代码(删除时)会大大提高性能。这不是评论可能会回答的问题。
  • @JosephWood 简单清单:代码是否已经按预期工作?问题中是否包含代码?它是完整的、未更改的代码吗? OP 是否需要关于其代码的任何/所有方面的一般、非特定反馈?典型的 CR 问题是“这是我的 X 代码,我怎样才能做得更好?”。
  • @Zak 和 syb0rg,感谢您的洞察力。
  • 不确定性能问题,但在deviceRotation 上同步是一个错误。只应使用最终对象。当deviceRotation 更改时,威胁将锁定在不同的事物上。

标签: java android multithreading synchronized


【解决方案1】:

您指出的代码很可能不是问题。模运算很慢,但每帧只做一次不会有很大的影响。 frameRotation 值被传递给onFrame(),我们只能假设它是应用矩阵或其他变换来旋转数据。这是一项昂贵的操作,很可能涉及使用一个或多个临时缓冲区(或Bitmap 对象),它使用堆并且速度也很慢。我假设 info.orientation 原封不动地传递给 onFrame() 不会导致框架调整。因此,删除您指出的 2 行将导致 onFrame() 中没有繁重的处理,这就是抖动消失的原因。

您可以使用 traceview 或 systrace 进行确认以更好地跟踪。

【讨论】:

    猜你喜欢
    • 2010-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-26
    • 1970-01-01
    • 2021-07-14
    • 1970-01-01
    • 2019-07-26
    相关资源
    最近更新 更多