틀딱 답게 C로 작성했엉
렉서는 저번에 만들어두어서
LALR 제네레이터 저번에 만든거 활용겸 해서
파서를 짜는데
수제작 파서는 손이 너무 많이 간다 ㅠ
솔직히 json은 그냥 재귀하강 더 잘 맞는듯!
회사에서 짠 json라이브러리는 해시테이블, AVLtree , 인덱싱, 더블링크드리스트 까지 적용되어 있는데
파싱은 LL로 함
이거는 그냥 대충 링크드 리스트로 구조만 잡고 끝남 LALR 파서도 버거웠음
...
렉서 최적화는
아래 링크 참고 많이 했엉
https://nothings.org/computer/lexing.html
요약을 하면 분기문을 최대한 줄이자임
텍스트 파싱할때 , 파싱과정보다. 토큰을 구해내는 스캔 과정이 더 부하가 많이 걸리니까
그쪽으로 최적화를 집중하는 느낌으로!
어떤 json 라이브러리는 SIMD까지 써서 개빠르더라고 ...
내가 최적화한 렉서는 do-while 문에서 분기가 while 조건 딱 하나밖에 없음
그러면 CPU가 분기예측을 항상 성공하고 마지막 탈출조건에서만 실패할테니까
최적화 하려고 적용한 리스트들
1. equal class 를 활용해서 0-9 같은문자가 한번 참조로 '숫자' 라는 하나의 클라스로 분류해낼수 있도록 사전테이블을 일단 둠
2. transition table 을 미리 다 만들어 놓고 상태이동만으로 토큰을 구함
3. 시작, 끝 포인터를 두고 상태에 따라서 시작포인터와, 끝 포인터를 증가시킬 플래그를 상태에 미리 저장
4. equal class 마저도 32비트 안에서 구역을 나누어 할당해서 , 상태에다가 어느부분을 읽어야할지 기록
5. 시작 포인터를 증가시킬때는 0,1 플래그를 읽고 '길이' 만큼 증가시켜야하는데
처음에는 곱셈으로 처리했다가. 곱셈도 무거운 연산이라서, 오버플로우랑 비트마스크를 활용함
s += (p - s) & (UINT_MAX + ((state>>9) & 0x1));
최적화 하느라고 코드를 보니까 너무 메모리 침범할 가능성이 많겠더라..
자꾸 보면볼수록 코드가 ㅄ같음 ㅠ
rb도 아니고 avl을 왜씀?
avl 무시하냐 ㅇㅅㅇ
알고리즘 수업때 교수님이 avl는 현업에선 절대 안쓴다고 했었는뎅
json object 해시테이블로만 쓰고 있는데, 혹시몰라서 트리로도 바꿀수 있게 하려고 구현하기 빠른쪽으로 대충 한겨 , json 정도 데이터량이면 RB,나 AVL나 딱히 별 , 절대 쓰지 말정도의 차이는 안나더라
이 댓글로 신경 겁나 쓰이네.. 교수가 안쓴다니까... 회사가서 싹다 rb 로 갈아엎어야겟다. - dc App
전에 이거 두개 차이를 인터넷에서 자세히 찾아봤는데, 정확한 말인지는 잘 모르겠음
일단 rb tree가 좀더 빠른건 맞다고 들음. rotation수가 적다나
근데 avl tree가 rb tree보다 더 균형이 잘 잡힘. 그래서 데이터가 많아질수록 모든 연산이 avl 쪽이 유리함 (insert, delete 상관 없이 전부)
어쨋든 전통적으로 RB를 많이 쓰는건 맞는데, 성능 부분에 있어서는 사람마다 이견이 있는것 같음
근데 json object를 내부 로직에 사용하는게 아니라 입출력 포멧으로만 쓸거면 Map 말고 그냥 key-value pair 리스트가 낫지 않나. HashMap, TreeMap 어떻게 뽑아 쓸지도 사용자가 선택할 수 있고
의외로 벤치마크에서는 AVL이 빠름. 굳이 쓰던거 바꿀 필요야