루비에서 많은 심볼을 동적으로 만드는 것이 좋은 생각이 아닌 이유는 무엇입니까?
루비에서 심볼의 기능은 무엇입니까? 문자열과 기호의 차이점은 무엇입니까? 많은 심볼을 동적으로 만드는 것이 좋은 생각이 아닌 이유는 무엇입니까?
기호는 문자열과 비슷하지만 변경할 수 없으며 수정할 수 없습니다.
한 번만 메모리에 저장되므로 해시의 키와 같은 작업에 매우 효율적으로 사용할 수 있지만 프로그램이 종료 될 때까지 메모리에 남아 있습니다. 이것은 당신이 그것들을 오용한다면 그것들을 기억의 돼지로 만듭니다.
많은 심볼을 동적으로 생성하는 경우 프로그램이 끝날 때까지 해제 할 수없는 많은 메모리를 할당하게됩니다. 다음 사항 string.to_sym
을 알고있는 경우 에만 동적으로 심볼을 만들어야합니다 (사용 ).
- 기호에 반복적으로 액세스해야 함
- 수정할 필요가 없습니다
앞서 말했듯 이, 변수 값보다 변수 의 신원 에 더 신경을 쓰는 해시와 같은 것에 유용 합니다. 올바르게 사용되는 경우 기호는 ID를 전달하는 읽기 쉽고 효율적인 방법입니다.
나는 당신의 코멘트 RE 기호의 불변성에 대해 내가 의미하는 바를 설명 할 것이다.
문자열은 배열과 같습니다. 제자리에서 수정할 수 있습니다.
12:17:44 ~$ irb
irb(main):001:0> string = "Hello World!"
=> "Hello World!"
irb(main):002:0> string[5] = 'z'
=> "z"
irb(main):003:0> string
=> "HellozWorld!"
irb(main):004:0>
기호는 숫자와 비슷합니다. 제자리에서 편집 할 수 없습니다.
irb(main):011:0> symbol = :Hello_World
=> :Hello_World
irb(main):012:0> symbol[5] = 'z'
NoMethodError: undefined method `[]=' for :Hello_World:Symbol
from (irb):12
from :0
심볼은 사용되는 위치에 관계없이 동일한 객체이며 동일한 메모리 할당입니다.
>> :hello.object_id
=> 331068
>> a = :hello
=> :hello
>> a.object_id
=> 331068
>> b = :hello
=> :hello
>> b.object_id
=> 331068
>> a = "hello"
=> "hello"
>> a.object_id
=> 2149256980
>> b = "hello"
=> "hello"
>> b.object_id
=> 2149235120
>> b = "hell" + "o"
동일한 문자를 포함한다는 점에서 '동일한'두 개의 문자열은 동일한 메모리를 참조하지 않을 수 있으며, 이는 해시와 같은 문자열을 사용하는 경우 비효율적 일 수 있습니다.
따라서 기호는 메모리 오버 헤드를 줄이는 데 유용 할 수 있습니다. 그러나-심볼은 생성 된 후에는 가비지 수집 할 수 없기 때문에 발생하기를 기다리는 메모리 누수입니다. 수천 개의 심볼을 생성하면 메모리가 할당되고 복구 할 수 없습니다. 이런!
어떤 종류의 화이트리스트 (예 : RoR의 쿼리 문자열 매개 변수의 경우)에 대해 입력을 검증하지 않고 사용자 입력에서 기호를 생성하는 것은 특히 나쁠 수 있습니다. 사용자 입력이 유효성 검사없이 기호로 변환되면 악의적 인 사용자가 프로그램이 가비지 수집되지 않는 많은 양의 메모리를 소비하게 할 수 있습니다.
불량 (사용자 입력에 관계없이 기호가 생성됨) :
name = params[:name].to_sym
양호 (사용자 입력이 허용되는 경우에만 기호가 생성됨) :
whitelist = ['allowed_value', 'another_allowed_value']
raise ArgumentError unless whitelist.include?(params[:name])
name = params[:name].to_sym
If you are using Ruby 2.2.0 or later, it should usually be OK to dynamically create a lot of symbols, because they will be garbage collected according to the Ruby 2.2.0-preview1 announcement, which has a link to more details about the new symbol GC. However, if you pass your dynamic symbols to some kind of code that converts it to an ID (an internal Ruby implementation concept used in the C source code), then in that case it will get pinned and never get garbage collected. I'm not sure how commonly that happens.
You can think of symbols as a name of something, and strings (roughly) as a sequence of characters. In many cases you could use either a symbol or a string, or you could use a mixture of the two. Symbols are immutable, which means they can't be changed after being created. The way symbols are implemented, it is very efficient to compare two symbols to see if they are equal, so using them as keys to hashes should be a little faster than using strings. Symbols don't have a lot the methods that strings do, such as start_with?
so you would have to use to_s
to convert the symbol into a string before calling those methods.
You can read more about symbols here in the documentation:
http://www.ruby-doc.org/core-2.1.3/Symbol.html
Starting Ruby 2.2 and above Symbols are automatically garbage collected and so this should not be an issue.
'program story' 카테고리의 다른 글
Pip을 사용하여 Python 패키지를 설치할 때 MinGW의 gcc 컴파일러를 사용하는 방법은 무엇입니까? (0) | 2020.12.01 |
---|---|
모든 vim 창을 한 번에 어떻게 다시로드합니까? (0) | 2020.12.01 |
텍스트 영역에서 커서 위치를 어떻게 얻습니까? (0) | 2020.12.01 |
작업 공간 파일을 변경하지 않고 다른 분기로 전환 (0) | 2020.12.01 |
$ .browser는 정의되지 않은 오류입니다. (0) | 2020.12.01 |