프로그래머스
ORM 사용시 쿼리가 복잡해지면 어떻게 할 것인가?공부하며 느낀 점
참조한 페이지
우선 나눠지는 원소부터 넣어보고, 예외처리와 정렬을 해보자.
예외처리는 깔끔하니 이제 정렬만하면 될것같다.
function solution(arr, divisor) {
var answer = [];
const length = arr.length
for (let i = 0 ; i < length ; i++){
if ( arr[i]%divisor === 0){
answer.push(arr[i])
}
}
if (answer.length === 0){
return [-1]
}
answer.sort((a,b)=> a-b)
return answer;
}
// 다른 사람의 풀이 1
function solution(arr, divisor) {
var answer = arr.filter(v => v%divisor == 0);
return answer.length == 0 ? [-1] : answer.sort((a,b) => a-b);
}
var answer = arr.filter(v => v%divisor == 0);
반복문이 아니라 filter로 딱 나눠지는 요소들만 걸러냈다.
return answer.length == 0 ? [-1] : answer.sort((a,b) => a-b);
이후 길이가 0이면 [-1]
을 리턴, 아니면 오름차순 정렬한다.
// 다른 사람의 풀이 2
function solution(arr, divisor) {
var answer = [];
arr.map((o) => {
o % divisor === 0 && answer.push(o);
})
return answer.length ? answer.sort((a, b) => a - b) : [-1];
}
비슷하지만 필터대신 맵을 사용하였다.
// 다름 사람의 풀이 3
function solution(arr, divisor) {
var _ = arr.filter(e => !(e%divisor));
return _[0] ? _.sort(($,_)=>$-_): [-1];
}
처음거랑 같은데 좀 보기 힘들게 만들어놨다...
아래의 조건으로 1천만회 반복을 하였다.
async function runSolutionWithTiming(solutionFn, arr, divisor) {
const startTime = new Date();
for (let i = 0; i < 10000000; i++) {
await solutionFn(arr);
}
const endTime = new Date();
const executionTime = endTime - startTime;
console.log(`${solutionFn.name} 실행 시간: ${executionTime}ms`);
}
async function main() {
const arr = [53, 29, 11, 76, 87, 5, 42, 64, 98, 34];
const divisor = 6;
await runSolutionWithTiming(solution0, arr, divisor);
await runSolutionWithTiming(solution1, arr, divisor);
await runSolutionWithTiming(solution2, arr, divisor);
await runSolutionWithTiming(solution3, arr, divisor);
}
main()
.then(() => {
console.log("모든 실행이 완료되었습니다.");
})
.catch((error) => {
console.error("에러 발생:", error);
});
솔루션 3의 경우 조건 !(e%divisor)
이 너무 복잡해서 오래 걸리는것같다.
우선 ORM을 사용하는 이유가 뭘까?
답은 쌩 쿼리를 쓰는것보다 훨씬 간단하기 때문이다. 하지만 그로 인해 속도를 잃게 된다. 왜냐하면 자바스크립트로 오브젝트를 만들고 DB와 매핑을 하기 때문이다. = 추상화
그리고 하나의 테이블이 아니라 여러 테이블을 조인하기 시작하면 ORM 구문이 로우 쿼리보다 더 복잡해 질 수 있다.
하지만 로우 쿼리로도 복잡하기 때문에 쿼리 빌더를 사용하는 것이 좋다고 한다.
그럼 ORM과 쿼리 빌더가 다른 점은 무엇인가?
쿼리 빌더를 사용할 경우의 이득
ORM을 사용할 경우의 이득
요약
1. 작동시간을 예측하는 것은 쉽지않다.
오늘 푼 프로그래머스 문제에서 나는 아래와 같이 속도를 예측했다.
내가 푼 방식 > 1,3 번 방식 > 2 번 방식
왜냐하면 1과 3은 표현이 조금 다를 뿐이지 같은 조건이고, 2번 방식은 map을 사용했다. 그러므로, 중간단계가 추가되었고, 그로 인해 더 느려질 것이라는 판단을 했기 때문이다.
실제로는 아래와 같았다.
내가 푼 방식 > 1,2 번 방식 > 3 번 방식
아마 map을 사용하나 filter를 사용하나 실제 속도 차이는 없고, 같은 조건처럼 보여도 부정연산자 !
가 하나 붙는 것이 생각 이상으로 큰 차이를 만들어 낸 것같다.
2. ORM이 무조건 좋은가? 에 대해 의문이 들었다.
본인도 프로젝트를 하다가 ORM으로 너무 복잡해서 팀원이 raw query를 사용하는 방식을 제안하였고 그것으로 더 좋은 결과를 냈었다. 단일 table이 아니라 여러 table을 참조해야하는 경우에는 raw query가 활실히 더 좋은 듯하며, query builder의 경우 써본적이 없기 때문에 아직은 이론적으로 밖에 모르겠다. 사용할 기회가 있다면 꼭 사용해봐야겠다.
ORM이냐 날쿼리냐 그것이 문제로다
[파이썬][Django] 복잡한 쿼리 작성 방법과 예제
[Django] 장고 ORM vs raw 비교하기
왜 Nodejs ORM을 쓰지 말아야 할까
Raw SQL vs Query Builder vs ORM