반복문 성능 비교

반복문에는 크게 for, while 문이 있다. while 문은 잘못하면 무한 루프에 빠지기 쉬우므로 for문을 권장한다.
또한  반복문 안에서 꼭 필요하지 않은 소스는 반복문 밖으로 추출시키도록 한다.
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
public class Sample {
 
  public static void main(String args[]) {
 
    List<Integer> list = new ArrayList<>();
    for (int i = 0; i < 10000; i++) {
      list.add(i);
    }
 
 
    for (int i = 0; i < list.size(); i++) { // #1
      System.out.println(list.get(i).toString());
    }
 
    int size = list.size();
    for (int i = 0; i < size; i++) { // #2
      System.out.println(list.get(i).toString());
    }
 
    for (Integer integer : list) { // #3
      System.out.println(integer.toString());
    }
 
  }
}
cs

위와 같은 반복문의 경우, 어떤 것이 가장 빠를까?
빠른 순서로 나열하면 다음과 같다. #2 > #1 > #3 

#1처럼 조건식에 list.size()를 사용하면 size() 메소드가 반복 호출된다. #2처럼 변수로 선언하여 사용하는 것이 좋다.
#3은 JDK 1.5부터 지원하는 향상된 for문이다. 배열이나 컬렉션에 저장된 요소들을 별도의 형변환이나 get 메소드가 필요없어 편리하게 처리할 수 있다.
단, 처음부터 끝까지 모든 요소를 반복할 때에 권장한다. 순서를 반대로하거나 특정 요소부터 탐색할 때에 부적절하다. 

물론 성능 차이가 얼마나지 않는다. 하지만 규모가 크거나 반복 횟수가 큰 경우 성능에 지장을 줄 수 있다.

'Development > Java' 카테고리의 다른 글

Garbage Collection 과정  (0) 2018.04.28
Garbage Collection 용어 정리  (0) 2018.04.26
AES256 암호화 오류 해결  (4) 2017.10.06
List 중복 제거  (0) 2017.07.13
Reflection 클래스 정보  (0) 2017.07.12
CORS(Cross-Origin Resource Sharing)


웹 개발시 JavaScript로 외부 서버에 ajax요청을 날리면 웹 브라우저의 콘솔창에 에러 메시지가 출력되면서 요청이 실패한다.
외부로 요청이 안되는 것은 JavaScript 엔진 표준 스팩에 동일 출처 정책이라는 보안 규칙이 있기 때문이다.

동일 출처 정책(Same-Origin Policy)
JavaScript(XMLHttpRequest)로 다른 웹 페이지에 접근할 때에 동일 출처의 페이지로만 접근이 가능하다. 
동일 출처라는 것은 프로토콜, 호스트명, 포트가 같은 것을 의미한다. 
즉 웹 페이지의 스크립트는 그 페이지와 같은 서버에 있는 주소로만 ajax 요청할 수 있다는 것이다.

이 정책이 초기에는 웹 사이트의 보안을 위한 좋은 방법으로 생각되었으나 최근들어 여러 도메인에 걸처서 구성되는 대규모 웹 프로젝트가 늘어나고, REST API 등을 이용한 외부 호출이 많은 상황에서는 까다로운 기술이기도 하다. 
그래서 CORS라는 정책이 만들어졌다. 특징으로는 서버에서 외부 요청을 허용할 경우 ajax요청이 가능해지는 방식이다.

CORS(Cross-Origin Resource Sharing)
CORS는 웹 페이지의 제한된 자원을 외부 도메인에서의 접근을 허용해주는 매커니즘이다.
브라우저와 서버간의 Cross-Origin 요청 허용여부를 안전하게 결정하도록 상호작용할 수 있는 방법을 정의한다.

요청 URL이 외부 도메인일 경우 웹 브라우저는 preflight 요청을 먼저 날린다. preflight 요청은 실제로 요청하려는 경로와 같은 URL에 대해 OPTIONS 메소드를 미리 날려 요청할 수 있는 권한이 있는지 확인한다. 서버로 넘어온 preflight  요청을 처리하여 웹 브라우저에서 실제 요청을 날릴 수 있도록 접근 허용 설정을 해줘야 한다. 권한이 없으면 에러를 발생시키고 권한이 있으면 실제 요청을 처리 해준다.

* Request headers (클라이언트의 요청 헤더)
Origin: 요청을 보내는 페이지의 도메인
Access-Control-Request-Method: 실제 요청하려는 메소드 종류
Access-Control-Request-Headers: 실제 요청에 포함되어 있는 헤더 이름

* Response headers (서버에서의 응답 헤더)
Access-Control-Allow-Origin: 요청을 허용하는 출처. * 인 경우, 모든 도메인의 요청을 허용한다.
Access-Control-Allow-Methods: 요청을 허용하는 메소드 종류. 헤더 값에 해당하는 메소드만 접근 허용한다. (default : GET, POST)
Access-Control-Allow-Headers: 요청을 허용하는 헤더 이름
Access-Control-Max-Age: 클라이언트에서 preflight 의 요청 결과를 저장할 시간(sec). 해당 시간동안은 preflight요청을 다시 하지 않게 된다.

위의 request header 값을 보고 response header에 해당 출처(origin)에 허용하는 요청 스펙을 허용해주도록 Filter나 Interceptor 등으로 구현해야 한다. 
아래와 같이 Spring Framework에서 제공하는 방법으로 구현할 수도 있다.

Controller method CORS configuration
@CrossOrigin 어노테이션을 사용하여 클래스/메소드 레벨로 정의하여 사용할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@CrossOrigin(maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {
 
    @CrossOrigin("http://domain.com")
    @RequestMapping("/{id}")
    public Account retrieve(@PathVariable Long id) {
        // ...
    }
 
    @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
    public void remove(@PathVariable Long id) {
        // ...
    }
}
cs

Global CORS configuration - Java Config
Spirng MVC 기반의 전역 설정으로 Filter와 흡사하고 @CrossOrigin과 함께 사용할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
             .allowedOrigins("http://domain.com")
             .allowedMethods("PUT""DELETE")
             .allowedHeaders("header1""header2""header3")
             .allowCredentials(false).maxAge(3600);
    }
}
cs

Filter based CORS support
Spring Framework 에서 지원하는 CorsFilter를 사용하거나 Custom하여 사용할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
 
public class MyCorsFilter extends CorsFilter {
 
    public MyCorsFilter() {
        super(configurationSource());
    }
 
    private static UrlBasedCorsConfigurationSource configurationSource() {
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("http://domain.com");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return source;
    }
}
cs

출처 - http://adrenal.tistory.com/16

List 중복 제거

자바에서 List에 있는 값들 중에 중복된 값만 제외시키고 싶은 경우가 있다.
루프를 돌면서 유니크한 값인지 비교하는 로직을 사용하고 싶지 않았다.
중복을 허용하지 않는 HashSet으로 변환시키고 다시 List로 변환시키면 유니크한 값으로 이루어진 List를 만들 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Sample {
 
    public static void main(String args[]) {
 
        List<String> items = new ArrayList<>();
        items.add("a");
        items.add("b");
        items.add("c");
        items.add("b");
        items.add("c");
        System.out.println(items); // ["a", "b", "c", "b", "c"]
 
  items = new ArrayList<>(new HashSet<>(items)); 
        System.out.println(items); // ["a", "b", "c"]
    }
}

cs

대소문자까지 중복된 값을 제외시킬 수 있는 좋은 방법 있으시면 피드백 부탁드립니다~

'Development > Java' 카테고리의 다른 글

Garbage Collection 과정  (0) 2018.04.28
Garbage Collection 용어 정리  (0) 2018.04.26
AES256 암호화 오류 해결  (4) 2017.10.06
반복문 성능 비교  (0) 2017.07.27
Reflection 클래스 정보  (0) 2017.07.12

+ Recent posts