더티 플래그

hipop1109·2025년 7월 12일

더티 플래그란?

더티 플래그는 불필요한 작업을 최대한 피하기 위해 그 일이 실제로 필요할 때까지 그 작업을 미루는 것을 말한다

값의 변경이 일어나야 하는 상황에 플래그를 설정해두어, 꼭 필요한 상황에만 갱신을 해주도록 하는 패턴이다.
만약 변화가 필요없을 때 다른 오브젝트의 영향을 받아서 연산을 해야하는 상황이 생긴다면 비효율적이고 퍼포먼스에 지장을 주기 때문이다


예를 들어 이런 식으로 4개의 오브젝트를 주르륵 자식으로 둔다고 치자

그럼 각 오브젝트들의 위치값은 상위 오브젝트 위치값으로부터 상대적인 위치값을 가진다
만약 그렇게 된다면 가장 하위 오브젝트의 월드 좌푯값을 얻기 위해 상위, 그 상위, 그 상위값의 모든 기준에서 위치값을 변환해줘야 한다는 결론이 나온다

반대로 생각해도 결론은 비슷하게 나온다
가장 상위 오브젝트를 이동시키면 그 아래 모든 3개의 오브젝트는 모두 계산이 되어야한다
만약 첫, 두, 세번째 위치값을 3번 이동시키면 마지막 오브젝트는 3번이나 움직이게 되는 현상이다

그래서 우리는 이런 쓸데없는 작업들을 피하기 위해 그 작업을 미룬다, 이걸 더티 플래그라고 한다.
시점은 계산, 동기화해야 할 때 사용된다
정리하면 어떠한 값이 사용되는 횟수보다 다른 현상에 의해 기본값이 변경되는 상황이 더 자주 있을 떄 유용한 방법이다.

코드로 조금 보자면

using UnityEngine;

public class MyTransform
{
    public Vector3 position;
    public Quaternion rotation;
    public Vector3 scale = Vector3.one;

    // 내부 캐시
    private Matrix4x4 localToWorldMatrix;
    private bool isDirty = true; // 더티 플래그

    public Vector3 Position
    {
        get => position;
        set
        {
            position = value;
            isDirty = true; // 값이 바뀌었으므로 더티
        }
    }

    public Quaternion Rotation
    {
        get => rotation;
        set
        {
            rotation = value;
            isDirty = true;
        }
    }

    public Vector3 Scale
    {
        get => scale;
        set
        {
            scale = value;
            isDirty = true;
        }
    }

    public Matrix4x4 LocalToWorldMatrix
    {
        get
        {
            if (isDirty)
            {
                // 값이 변경되었으므로 새로 계산
                localToWorldMatrix =
                    Matrix4x4.TRS(position, rotation, scale);
                isDirty = false; // 깨끗해짐
            }
            return localToWorldMatrix;
        }
    }
}
MyTransform t = new MyTransform();
t.Position = new Vector3(1, 2, 3);

// 처음 접근 시 계산
Matrix4x4 m1 = t.LocalToWorldMatrix;

// 다시 접근 시 계산 안 함 (변경 없으므로)
Matrix4x4 m2 = t.LocalToWorldMatrix;

// 값 변경 시 다시 Dirty
t.Rotation = Quaternion.Euler(0, 90, 0);

// 다음 접근 시 새로 계산
Matrix4x4 m3 = t.LocalToWorldMatrix;

이런 식으로 isDirty가 상태 변경 여부를 표시하면서 값이 바뀌면 isDirty를 true로 하고 작업 수행 후에넌 false로 초기화하면서 불필요한 연산을 방지하게 된다.
간단히 정리하자면 걸어놨다가 몰아서 연산해서 불필요한 연산을 방지한다~라는 개념으로 보면 된다

주의점 1 : 너무 오래 지연하려면 비용이 든다

만약 작업을 할때 위 상황이 생겼을 때, 지연 시간이 적절히 조절되지 않고 너무 오래 지연된다면 타이밍 자체가 꼬이면서 오류가 발생할 수 있다는 것이다.
보통 작업이 전부 날아갈 수 있다는 휘험성이 존재한다.

주의점 2 : 상태가 변할 때마다 플래그를 켜야함

아래 값은 기본 값으로부터 계산되기 때문에, 기본 값을 변경하는 모든 상황에 더티 플래그 설정이 따라온다는 문제점이 있다.
만약 더티 플래그를 설정하지 않은 다른 외부 코드에서 값을 바꾼다면 의미가 사라짐

주의점 3 : 이전 값을 메모리에 저장해둬야 한다.

과거에 저장된 값을 쓰려면 결론적으론 당연이 이전 값을 메모리에 저장해놨다 써야한다, 속도를 위해 메모리를 희생한다는 뜻
메모리보다 시간이 남는다면 굳이...?

profile
쑥쑥 개발자

0개의 댓글