JSON과 STRING의 성능검사

2024년 6월 14일 금요일

Today I Learned

날짜

2024년 6월 14일 금요일

내용

앱 메타필드(2)

어제 무사히(?) 앱 메타필드를 저장하는 방법을 알아냈다고 생각했으나, 오늘 왠지 또 잘 안됐다. 원인은 정확히 앱 메타필드가 어디에 어떤값으로 있는지 몰라서 발생한 일이었다. 우리야 “앱 메타필드”라고 부르지만, 정확하겐 appInstallation 이라는 객체 내에 있는 Metafield 안에 저장하는 것이다. 기존에 사용하던 샵 메타필드는 Shop 객체 안에있고..

따라서 우리 앱의 appInstallation ID를 알아내기 위해, 고객이 우리 앱을 설치하자마자 currentappInstallation을 조회하여 저장하고, 이 객체 안 메타필드를 관리하면 된다. 이 ID값은 key나 namespace가 아닌 ownerID 라는 항목의 값으로 처리된다.

img

JSON vs String 성능

1
2
3
4
5
6
7
8
9
metafields = [
            {
                "key": key,
                "namespace": namespace,
                "ownerId": self.shop.app_id,
                "type": "json",
                "value": json.dumps(value),
            },
]

메타필드는 이런 key와 value로 이루어져있다. 이 중 value 가 저장하고자 하는 내용이다. 이번 스프린트에서 모든 데이터가 포함된 HTML 전체를 메타필드에 저장하기로 했다. 스토어에선 앱 프록시를 이용해 우리 서버에 위젯 렌더링을 요청할 필요 없이, 메타필드에서 가져다가 쓰면 된다. 이 HTML을 string으로 저장할지, json으로 저장할지 고민됐다. 쇼피파이 Docs에선 string 타입에 대한 언급이 없었는데, judgeme 같은 다른 앱에선 string으로 저장하고 있길래…

뭐가 좋을까 고민하다가, 두 개가 성능상 차이는 없을까 고민했다. 위젯에 관한 설정값을 데이터베이스에 저장했을때와 달리, 유저가 수정하는 모든 사항은 메타필드에 업로드되야 해야한다.메타필드에 어떻게 저장하느냐에 따라 요청의 시간차가 있을지 궁금했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@router.post("/facebook/app-metafields")
def create_app_metafields(
    shop_platform_id: int,
    db: Session = Depends(get_db),
):
		# 100회 반복
		cnt = 0
		arr = []
		while cnt < 100:
		# 함수가 호출된 시점의 시간
			start = datetime.datetime.now()
	    stmt = select(models.InstagramCommentsShop).options(joinedload(models.InstagramCommentsShop.instagram_comments_widget_setting)).where(
	        models.InstagramCommentsShop.shop_platform_id == shop_platform_id
	    )
	    
        ...
	    
	    # 함수 종료 직전 시점의 시간
	    end = datetime.datetime.now()
	    time_to_proceed = end - start
	    arr.append(time_to_proceed)
		  
	# 평균 시간, 최상위 값과 최하위 값 출력
	print(f"average : {sum(arr)/100}")
	print(f"max : {max(arr)}")
	print(f"min : {min(arr)}")
	return result

이렇게 설정하고, 각각 json 타입일때와 string 타입일때의 시간을 비교했다.

json

average:  0:00:00.474161

max:  0:00:00.652730

min:  0:00:00.387196

string

average:  0:00:00.485785

max:  0:00:01.044374

min:  0:00:00.391719

평균은 10ms 정도로 큰 차이가 없었는데, string의 경우 최악의 상황에서 값이 상당히 컸다. 그럼에도 평균이 비슷하다는건, 중간값은 string이 높을지도 모르겠다.

(1) shopify Docs 상 string은 나타나있지 않다는 점

(2) 상대적으로, 모든 요청의 시간 소요가 고르다는 점

을 이유로 json으로 처리하기로 했다. 지금 생각해보면, 최하위 와 최상위 값을 1개만 표시하지 않고 5개 정도 확인해볼 걸 그랬다.

회고

거진 다 왔다.