program story

루비에서 많은 심볼을 동적으로 만드는 것이 좋은 생각이 아닌 이유는 무엇입니까?

inputbox 2020. 12. 1. 07:58
반응형

루비에서 많은 심볼을 동적으로 만드는 것이 좋은 생각이 아닌 이유는 무엇입니까?


루비에서 심볼의 기능은 무엇입니까? 문자열과 기호의 차이점은 무엇입니까? 많은 심볼을 동적으로 만드는 것이 좋은 생각이 아닌 이유는 무엇입니까?


기호는 문자열과 비슷하지만 변경할 수 없으며 수정할 수 없습니다.

한 번만 메모리에 저장되므로 해시의 키와 같은 작업에 매우 효율적으로 사용할 수 있지만 프로그램이 종료 될 때까지 메모리에 남아 있습니다. 이것은 당신이 그것들을 오용한다면 그것들을 기억의 돼지로 만듭니다.

많은 심볼을 동적으로 생성하는 경우 프로그램이 끝날 때까지 해제 할 수없는 많은 메모리를 할당하게됩니다. 다음 사항 string.to_sym을 알고있는 경우 에만 동적으로 심볼을 만들어야합니다 (사용 ).

  1. 기호에 반복적으로 액세스해야 함
  2. 수정할 필요가 없습니다

앞서 말했듯 이, 변수 값보다 변수 신원더 신경을 쓰는 해시와 같은 것에 유용 합니다. 올바르게 사용되는 경우 기호는 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.

참고URL : https://stackoverflow.com/questions/4573991/why-is-it-not-a-good-idea-to-dynamically-create-a-lot-of-symbols-in-ruby

반응형