ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • static, const, memoization
    Technique/PHP 2016. 12. 20. 18:21
    반응형

    1. Static


    정적, 공유의 개념

    static은 변수 또는 메소드 등에 지정할 수 있으며, 메소드에 지정한 경우 객체를 생성하지 않고도 접근이 가능하다.

    이 정적 메소드 안에서 연산이 이뤄질 때엔 멤버 변수에 접근할 수 없다.

    즉, static 메소드 안에서 사용되는 변수는 static이어야만 한다.

    이것이 중요한 룰!

    static변수는 프로그램이 실행 될 시 단한번 초기화가 된다.

    그리고 메모리 상에 데이터가 보존되어 그이후 호출은 모두 메모리를 참조하여 접근 하게 된다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class A
    {
        public static $abc = null;
        public static function getAbc()
        {
            return A::$abc;
        }
    }
     
    $a1 = new A();
    $a2 = new A();
     
    var_dump( $a1::getAbc() );  // null
    var_dump( $a2::getAbc() );  // null
    cs


    위의 코드를 보면 스태틱 변수를 리턴하는 함수 인 getAbc()가 있다

    위에도 설명 했지만 static함수에서 멤버변수로의 접근은 허용하지 않는다. 오로지 static변수일 경우만 사용이 가능하다.

    그래서 결과가 NULL임을 확인 할 수 있다. 

    자 그럼 스태틱을 이용하는 것에 대해 간단히 보자면 


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    class A
    {
        public static $abc = null;
        public static function getAbc()
        {
            return A::$abc;
        }
    }
     
    $a1 = new A();
    $a2 = new A();
     
    $a1::$abc = "suzy";
     
    var_dump( $a1::$abc ); // suzy
    var_dump( $a2::$abc ); // suzy
    cs


    위와 같이 코드가 작성 가능하다.

    분명히 abc의 값을 변화 시킨 것은 a1의 abc뿐이지만 결과 적으론 a2의 값도 변화 하였다.

    이처럼 프로그램 내의 동일한 변수를 사용하고자 할때엔 static을 이용하면 손쉽게 구현할 수 있다.


    2.Memoization


    프로그램을 실행함에 있어 같은 결과가 반복되는 행동을 메모리에 올려두어 불필요한 리소스 사용을 막고, 실행 속도를 증가 시키는 최적화 기법중 하나이다.

    부가적으로 설명하자면 프로그램을 실행하는데 사용되는 함수가 있는데 그 함수 안에선 for와 while이 난무하여 수천, 수만번 루프가 이루어 지는 아주 복잡한 코드이다. 하지만 그 결과 는 1000이고 이 결과는 언제 실행시켜도 항상 1000이 return된다고한다면, 이 함수를 부를때마다 수천, 수만번의 루프가 돌아가고 복잡한 연산이 움직이는데 계속 같은 결과 값만을 리턴한다. 이 얼마나 불필요한 리소스 소모 인가.

    그때문에 이 함수를 static이라 지정하여 메모리위에 이 함수의 결과 값을 상주 시켜 둔다면 이함수가 불릴때 마다 수많은 연산은 다 패스하고 그 결과 값만 리턴 시켜주면 된다. 아주 깔끔하다.

    위에도 설명 하였듯 연산의 결과가 항상 같다는 전제가 필요하다. 


    준비물 : BenchMark 클래스


    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    class Benchmark
    {
        private $start_time;
        private $end_time;
        private $init_memory;
        private $fini_memory;
        private $peak_memory = 'unknown (PHP 5 >= 5.2.0)';
        private $format;
     
        public function __construct($format = '%.6f sec / init_mem: %s KB / fini_mem: %s KB / peak_mem: %s KB')
        {
            $this->start_time = 0;
            $this->end_time   = 0;
            $this->format     = $format;
        }
     
        public function start()
        {
            $this->start_time = $this->microtimeFloat();
            $this->init_memory = number_format(round(memory_get_usage() / 10242));
        }
     
        public function stop()
        {
            $this->end_time = $this->microtimeFloat();
            $this->fini_memory = number_format(round(memory_get_usage() / 10242));
     
            if (version_compare(PHP_VERSION, '5.2.0''>=')) {
                $this->peak_memory = number_format(round(memory_get_peak_usage() / 10242));
            }
     
            return sprintf(
                            $this->format,
                            $this->end_time - $this->start_time,
                            $this->init_memory,
                            $this->fini_memory,
                            $this->peak_memory
                            );
        }
     
        private function microtimeFloat()
        {
            list($usec, $sec) = explode(' ', microtime());
            return ((float)$usec + (float)$sec);
        }
    }
    cs


    간단한 벤치마크 클래스이다. start와 stop를 통하여 경과된 시간, 메모리 소모율을 표기한다.


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    function hoge($min, $max)
    {
        static $ret = array();
        if (isset($ret[$min][$max])){
            return $ret[$min][$max];
        }
     
        $buf = 0;
        foreach (range($min, $max) as $i) {
            $buf += $i;
        }
        $ret[$min][$max] = $buf;
     
        return $ret[$min][$max];
    }
     
    $bench = new Benchmark();
    $bench->start();
    var_dump( '1회호출: '.hoge(1100000) );
    var_dump( $bench->stop() );
     
    $bench->start();
    var_dump( '2회 호출: '.hoge(1100000) );
    var_dump( $bench->stop() );
    cs



    위와 같은 결과를 얻을 수 있다.

    연산 결과를 메모리에 저장시켜두었기에 추가적인 메모리 소모도 생기지 않았고, 결과를 돌려받는 속도또한 대단하 빨라졌다는 것을 알 수 있다.


    3. const


    const는 상수이다. 

    즉 변하지 않고, 변화 시키려 해서도 안된다. fatal에러가 반겨줄 것이다.

    범위는 하나의 class내 에서 사용 가능하며 본인이 접근하려면

    self::const변수 로 가능하고

    상속하여 사용할시

    parent::const변수

    그리고 그외엔 class명::const변수명 으로만 접근가능하다.

    즉 인스턴스::변수명 으론 접근이 불가능 하다는 소리이다.

    절대 변화 해선 안되는 변수가 필요한 경우 사용하면 아주 좋다.

    예시론 const HOST = "ABCD" 로 설졍한다면 만약 HOST가 변화 하더라도 선언하는 부분만 수정해준다면 이 HOST를 사용하는 부분에선

    모두다 바뀐 값이 적용 된 것을 알수 있다.

     

    좀더 넓은 범위 즉 global적인 느낌으로 사용 하고 싶다면 define을 사용하면 된다.



    반응형

    'Technique > PHP' 카테고리의 다른 글

    Laravel 6.x Passport 를 이용한 API인증  (0) 2020.01.23
    LSB(Late Static Binding)  (0) 2016.12.21
    1,0 true, false  (0) 2016.12.07
    setcookie  (0) 2016.05.09
    money_format  (0) 2016.04.15

    댓글

Designed by Tistory.