본문 바로가기
728x90

카테고리249

아이템 51 - 성능이 중요한 부분에는 기본 자료형 배열을 사용하라 성능이 중요한 코드 영역에서 기본 자료형 배열(Primitive Arrays)을 사용하는 것이 좋습니다. 기본 자료형 배열은 JVM에서 직접 메모리를 관리하며, 일반적인 컬렉션보다 성능 면에서 많은 이점을 제공합니다. 기본 자료형 배열을 사용하면 다음과 같은 이점이 있다.메모리 효율성: 기본 자료형 배열은 객체를 감싸지 않고 원시 데이터 자체를 저장하므로, 메모리 오버헤드가 적습니다. 예를 들어, IntArray는 정수값을 직접 저장하므로, List와 달리 각각의 정수가 별도의 객체로 관리되지 않습니다.성능 최적화: 기본 자료형 배열은 JVM이 직접 관리하므로, 연산 속도가 빠르고 캐시 효율성이 높습니다. 이로 인해, 대규모 데이터 처리를 할 때 성능이 크게 개선됩니다.간단한 데이터 구조: 기본 자료형 .. 2024. 8. 18.
아이템 50 - 컬렉션 처리 단계 수를 제한하라 컬렉션 처리 메서드는 비용이 많이 든다.적절한 메서드를 활용해서, 컬렉션 처리 단계 수를 적절하게 제한하는 것이 좋다// 비효율적인 코드val result = listOf(1, 2, 3, 4, 5) .map { it * 2 } .filter { it > 3 } .map { it + 1 } .filter { it 3 && it    .filter { it != null }.map { it!! }.filterNotNull().map { }.filterNotNull().mapNotNull { }.map { }.joinToString().joinToString { }.filter { }.filter { }.filter { && }.filter { it is Type }.ma.. 2024. 8. 18.
아이템 49 - 하나 이상의 처리 단계를 가진 경우네는 시퀀스를 사용하라 코틀린에서 컬렉션을 처리할 때, 다음과 같은 코드가 자주 사용됩니다:val numbers = listOf(1, 2, 3, 4, 5)val result = numbers .map { it * 2 } .filter { it > 5 } .map { it + 1 }println(result) // [7, 9, 11] 해당 코드는 map, filter 가 연속적으로 호출된다. 이런 방식은 각 단계마다 새로운 리스트를 생성하므로, 처리 단계가 많아질수록 불필요한 리스트 생성이 발생하고 성능이 저하될 수 있다. 이러한 문제를 해결하기 위해 코틀린은 시퀀스를 제공한다.시퀀스는 중간 처리 단계를 거칠 때마다 새로운컬렉션을 생성하지 않고, 필요할 때마다 요소를 하나씩 처리하는 lazy 방식을 사용한다.va.. 2024. 8. 18.
jmh 오..jmh 써보신분??궁금해서 써봤는데..*JMH란? JMH는 OpenJDK에서 개발한 성능 측정 툴이다. 특정 메소드의 성능을 측정하는 식으로 사용할 수 있고 실제 테스트하기전 워밍업 과정과 실제 측정 과정을 수행하는데 각 과정의 실행 수를 제어할 수 있고, 측정 후 결과로 나오는 시간의 단위를 지정하는 기능도 제공한다.===저번 코틀린 스터디 중에 asSequence 얘기나왔었는데..어쩌다가 성능비교해봤네용 저도 코드 복붙복붙기준: 200만개 stream 이용한 -> filter, map, take, average 로 간단한 구현 각 1회 warmUp 처리1.iterator : 20초2.asSequence: 0.4초궁금하신분은?https://github.com/melix/jmh-gradle-plugin 2024. 8. 18.
sendWarmUpRequest 한번 호출해 놓으면 왜 빨라질까? WebClient를 통해 API 호출을 한 번 수행하면 이후 요청이 더 최적화될 수 있습니다. 이 최적화는 주로 커넥션 풀링과 DNS 조회 최적화에서 발생합니다. 아래에서 각 최적화가 어떻게 이루어지는지 설명드리겠습니다.1. 커넥션 풀링(Connection Pooling)커넥션 풀링은 클라이언트(예: WebClient)와 서버 간의 네트워크 연결을 재사용하여 성능을 최적화하는 방법입니다. 다음은 커넥션 풀링이 어떻게 이루어지는지에 대한 설명입니다:TCP 연결 재사용:WebClient는 HTTP 요청을 보낼 때 TCP 연결을 사용합니다. 이 TCP 연결은 설정하는 데 일정한 오버헤드(예: 3-way handshake)가 필요합니다.첫 번째 요청이 발생하면 WebClient는 서버와의 TCP 연결을 설정합니.. 2024. 8. 18.
아이템 46 - 함수 타입 파라미터를 갖는 함수에 inline 한정자를 붙여라 inline 한정자의 역할은 컴파일 시점에 '함수를 호출하는 부분'을 '함수의 본문' 으로 대체하는 것koltin 에서는 고차함수(함수를 인자로 받거나 반환하는 함수)를 사용할 수 있다.고차 함수는 성능에 영향을 미칠 수 있는데, 이는 함수 타입 파라미터를 갖는 함수를 호출할 때마다 새로운 함수 객체가 생성되고 이러한 함수 객체는 런타임 시점에 인라인되지 않기 때문에 오버헫가 발생할 수 있다.  일반적인 함수를 호출하면 함수 본문으로 점프하고, 본문의 모든 문장을 호출한 뒤에 함수를 호출했던 위치로 다시 점프 하는 과정을 거친다.하지만 함수를 호출하는 부분을 함수의 본문으로 대체하면 이러한 점프가 일어나지 않는다. inline 한정자를 사용하면 다음과 같은 장점이 있다.타입 아규먼트에 refied 한정자.. 2024. 8. 16.
아이템 45 - 불필요한 객체 생성을 피하라 객체 생성은 언제나 비용이 들어갑니다.상황에 따라 굉장히 큰 비용이 들어갈 수도 있습니다.따라서 불필요한 객체 생성을 피하는 것이 최적화의 관점에서 좋습니다JVM 에서는 하나의 가상 머신에서 동일한 문자열을 처리하는 코드가 여러 개 있다면, 기존의 문자열을 재사용합니다.문자열 상수의 재사용 (String Pool)JVM에서 문자열은 불변(immutable) 객체입니다. 즉, 한 번 생성된 문자열은 변경할 수 없습니다. JVM은 이러한 문자열의 특성을 활용하여 String Pool이라는 메모리 공간을 사용합니다.String Pool이란?String Pool은 JVM이 관리하는 특별한 메모리 영역으로, 동일한 문자열 리터럴이 여러 번 생성되는 것을 방지하고 메모리를 절약하기 위해 사용됩니다.만약 코드에서 동.. 2024. 8. 10.
아이템 44 - 멤버 확장 함수의 사용을 피하라 어떤 클래스에 대한 확장 함수를 정의할 때 이를 멤버로 추가하는 것은 좋지 않습니다.확장 함수는 첫 번째 아규먼트로 리시버를 받는 단순한 일반 함수로 컴파일됩니다. 왜 멤버 확장 함수를 피해야 하는가?혼란스러운 함수 스코프:멤버 확장 함수는 해당 함수가 어디서 사용 가능한지, 또는 어떤 클래스에 속하는지 혼동을 일으킬 수 있습니다. 예를 들어, 함수가 멤버 함수인지 확장 함수인지 명확하지 않으며, 사용 범위가 제한되기 때문에 코드의 가독성을 해치게 됩니다.예상치 못한 동작:멤버 확장 함수는 일반적인 확장 함수와 다르게 동작할 수 있습니다. 특정 클래스 내부에서만 접근 가능한 확장 함수는 그 클래스의 외부에서는 전혀 보이지 않으며, 이는 코드의 일관성을 깨트리고 예상치 못한 동작을 초래할 수 있습니다.코드.. 2024. 8. 10.
아이템 43 - API 의 필수적이지 않는 부분을 확장 함수로 추출하라 클래스의 메서드를 정의할 때는 메서드를 멤버로 정의할 것인지 아니면 확장 함수로 정의할 것인지 결정해야 합니다. 멤버 함수로 정의한 경우class Circle(val radius: Double) { // 멤버 함수로 정의된 메서드 fun area(): Double { return Math.PI * radius * radius }}fun main() { val circle = Circle(5.0) println("Area: ${circle.area()}") // 멤버 함수 호출} 확장 함수로 정의한 경우class Circle(val radius: Double)// 확장 함수로 정의된 메서드fun Circle.area(): Double { return Math... 2024. 8. 10.
728x90