C ++ 11에서 COW std :: string 구현의 합법성


117

copy-on-write는 std::stringC ++ 11에서 준수를 구현하는 실행 가능한 방법이 아니라는 것을 이해 했지만 최근 논의에서이 내용을 직접 지원할 수 없다는 것을 알게되었습니다.

C ++ 11이 COW 기반 구현을 인정하지 않는다는 것이 맞 std::string습니까?

그렇다면이 제한이 새로운 표준 (어디)의 어딘가에 명시 적으로 명시되어 있습니까?

또는 std::stringCOW 기반 구현을 배제하는 새로운 요구 사항의 결합 된 효과라는 의미에서 이러한 제한이 내포 되어 있습니까 std::string? 이 경우 'C ++ 11은 COW 기반 std::string구현을 효과적으로 금지합니다'의 장과 절 스타일 파생에 관심이 있습니다 .


5
COW 문자열에 대한 GCC 버그는 gcc.gnu.org/bugzilla/show_bug.cgi?id=21334#c45 입니다. libstdc ++에서 std :: string의 새로운 C ++ 11 컴파일
user7610

답변:


120

표준 21.4.1 p6에 따라 반복자 / 참조의 무효화는 다음에 대해서만 허용되기 때문에 허용되지 않습니다.

— 상수가 아닌 basic_string에 대한 참조를 인수로 사용하는 표준 라이브러리 함수에 대한 인수로.

— operator [], at, front, back, begin, rbegin, end 및 rend를 제외한 상수가 아닌 멤버 함수 호출.

COW 문자열의 경우 non-const를 호출 operator[]하려면 복사본을 만들고 참조를 무효화해야하는데, 이는 위 단락에서 허용하지 않습니다. 따라서 C ++ 11에서 COW 문자열을 갖는 것은 더 이상 합법적이지 않습니다.


4
몇 가지 근거 : N2534
MM

8
-1 논리는 물을 보유하지 않습니다. COW 복사시에는 무효화 할 수있는 참조 나 반복기가 없습니다. 복사를 수행하는 요점은 이러한 참조 나 반복기가 현재 확보되고 있다는 것이므로 복사가 필요합니다. 그러나 여전히 C ++ 11은 COW 구현을 허용하지 않을 수 있습니다.
건배와 hth. - 알프

11
@ Cheersandhth.-Alf : COW가 허용 된 경우 논리는 다음에서 볼 수 있습니다. std::string a("something"); char& c1 = a[0]; std::string b(a); char& c2 = a[1]; c1은 a에 대한 참조입니다. 그런 다음 "복사"a. 그런 다음 두 번째로 참조를 가져 오려고하면 동일한 버퍼를 가리키는 두 개의 문자열이 있으므로 상수가 아닌 참조를 가져 오기 위해 복사본을 만들어야합니다. 이것은 취해진 첫 번째 참조를 무효화해야하며 위에 인용 된 섹션에 위배됩니다.
Dave S

9
@ Cheersandhth. - 알프에 따라 적어도 GCC의 COW 구현 않습니다 DaveS 말을 정확히 않습니다. 따라서 최소한 그 스타일의 COW는 표준에 의해 금지됩니다.
Tavian Barnes

4
@Alf :이 대답은 non-const operator[](1)는 반드시 복사본을 만들어야하며 (2) 그렇게하는 것은 불법이라고 주장합니다. 이 두 가지 중 어떤 점에 동의하지 않습니까? 첫 번째 주석을 보면 구현이 적어도이 요구 사항에 따라 액세스 할 때까지 문자열을 공유 할 수 있지만 읽기 및 쓰기 액세스 모두 공유를 해제해야합니다. 그게 당신의 추론입니까?
Ben Voigt 2015 년

48

Dave Sgbjbaanb 의 대답 은 정확합니다 . (그리고 Luc Danton의 경우도 정확하지만 COW 문자열을 금지하는 원래 규칙보다 더 많은 부작용이 있습니다.)

그러나 약간의 혼란을 없애기 위해 좀 더 설명을 추가 할 것입니다. 다양한 댓글 은 다음 예제를 제공하는 GCC 버그질라에 대한 내 댓글에 연결됩니다 .

std::string s("str");
const char* p = s.data();
{
    std::string s2(s);
    (void) s[0];
}
std::cout << *p << '\n';  // p is dangling

이 예제의 요점은 GCC의 COW (reference counted) 문자열이 C ++ 11에서 유효하지 않은 이유를 보여주는 것입니다. C ++ 11 표준이 올바르게 작동하려면이 코드가 필요합니다. 코드의 어떤 것도 pC ++ 11에서 무효화 되는 것을 허용하지 않습니다 .

GCC의 이전 참조 카운트 std::string구현을 사용하면 해당 코드 p 무효화되어 매달려 포인터가되기 때문에 정의되지 않은 동작 을가집니다. (무슨 일 때이다 s2구성되어 그것과 데이터를 공유 s하지만, 비아 비 CONST 참조 구하기 s[0]때문에, 데이터는 비공유 요구 s기준이 때문에 "이 기록 복사"않는 s[0]잠재적으로 기록하는 데 사용될 수 s후, s2진행 범위를 벗어나는 배열을 파괴하는 단계에 의해 지시 p).

C ++ 03 표준 은 21.3 [lib.basic.string] p5에서 해당 동작명시 적으로 허용합니다. 여기서 data()첫 번째 호출에 대한 호출 이후에 operator[]()포인터, 참조 및 반복기를 무효화 할 수 있습니다. 따라서 GCC의 COW 문자열은 유효한 C ++ 03 구현이었습니다.

(11) 표준 C ++ 더 이상 허용 에는 호출이 있기 때문에, 그 동작을 operator[]()에 관계없이 그들에 대한 호출을 수행 여부, 포인터, 참조 또는 반복자를 무효화 할 수 없다 data().

따라서 위의 예 는 C ++ 11에서 작동 해야 하지만 libstdc ++의 종류의 COW 문자열에서는 작동 하지 않습니다 . 따라서 이러한 종류의 COW 문자열은 C ++ 11에서 허용되지 않습니다.


3
호출 .data()(및 포인터, 참조 또는 반복자의 모든 반환)에서 공유를 해제하는 구현 은 해당 문제를 겪지 않습니다. 즉 (불변) 버퍼는 언제든지 공유되지 않거나 외부 참조없이 공유됩니다. 이 예제에 대한 주석을 비공식적 인 버그 보고서 (주석으로보고)로 의도했다고 생각했습니다. 오해를해서 매우 죄송합니다! 그러나 여기에 설명 된 것과 같은 구현을 고려하여 볼 수 있듯이 noexcept요구 사항이 무시 될 때 C ++ 11에서 잘 작동합니다 . 예제에서는 형식에 대해 아무 말도하지 않습니다. 원하는 경우 코드를 제공 할 수 있습니다.
건배와 hth. - 알프

7
문자열에 대한 거의 모든 액세스에서 공유를 해제하면 공유의 모든 이점을 잃게됩니다. COW 구현은 표준 라이브러리에서이를으로 사용하는 데 실용적 이어야 std::string하며 C ++ 11 무효화 요구 사항을 충족하는 유용하고 성능이 뛰어난 COW 문자열을 보여줄 수 있는지 진심으로 의심합니다. 그래서 noexcept마지막 순간에 추가 된 사양은 근본적인 이유가 아니라 COW 문자열 금지의 결과라고 주장합니다. N2668은 완벽하게 분명해 보입니다. 왜 거기에 설명 된위원회의 의도에 대한 분명한 증거를 계속 부인합니까?
조나단 Wakely

또한 data()이것은 const 멤버 함수이므로 다른 const 멤버와 data()동시에 호출하고 예를 들어 문자열의 복사본을 만드는 다른 스레드와 동시에 호출하는 것이 안전해야 합니다. 따라서 모든 문자열 작업, 심지어 const 작업 에 대한 뮤텍스의 모든 오버 헤드가 필요 하거나 잠금없는 가변 참조 카운트 구조의 복잡성이 필요하며 결국 수정하거나 액세스하지 않는 경우에만 공유 할 수 있습니다. 당신의 문자열, 너무 많은, 많은 문자열은 1의 참조 카운트를 가질 것입니다. 코드를 제공하고 noexcept보증 을 무시해도 됩니다.
조나단 Wakely

2
코드 몇 개를 조합 해보면 129 개의 basic_string멤버 함수와 자유 함수 가 있다는 것을 알게되었습니다 . 추상화 비용 : 최적화되지 않은이 새로운 제로 버전 코드는 g ++ 및 MSVC 모두에서 50 ~ 100 % 더 느립니다. 스레드 안전을 수행하지 않으며 ( shared_ptr제 생각에 충분히 활용하기 쉽습니다 ) 타이밍을 위해 사전 정렬을 지원하는 것으로 충분하지만 모듈로 버그 basic_string는 C ++ noexcept요구 사항을 제외하고 계산 된 참조 가 허용 된다는 점을 증명합니다 . github.com/alfps/In-principle-demo-of-ref-counted-basic_string
건배 및 hth. - 알프


20

CoW는 더 빠른 문자열을 만드는 데 허용되는 메커니즘이지만 ...

다중 스레딩 코드를 느리게 만듭니다 (여러 문자열을 사용할 때 작성하는 유일한 사람인지 확인하는 모든 잠금으로 인해 성능이 저하됩니다). 이것이 CoW가 몇 년 전에 살해 된 주된 이유였습니다.

다른 이유는 []연산자가 다른 사람이 변경하지 않을 것으로 예상되는 문자열을 덮어 쓰지 않도록 보호하지 않고 문자열 데이터를 반환하기 때문입니다. c_str()및 에도 동일하게 적용됩니다 data().

Quick google은 다중 스레딩이 기본적으로 명시 적으로 허용되지 않은 이유 라고 말합니다 .

제안 내용 :

신청

모든 반복자와 요소 액세스 작업을 동시에 안전하게 실행할 수 있도록 제안합니다.

순차 코드에서도 작업의 안정성을 높이고 있습니다.

이 변경으로 인해 COW (Copy-On-Write) 구현이 효과적으로 허용되지 않습니다.

뒤에

COW (Copy-On-Write) 구현에서 전환으로 인한 성능 저하의 가장 큰 원인은 대부분의 읽기 문자열이 매우 큰 응용 프로그램의 메모리 소비 증가입니다. 그러나 우리는 이러한 응용 분야에서 로프가 더 나은 기술 솔루션이라고 믿으며 라이브러리 TR2에 포함될 로프 제안을 고려할 것을 권장합니다.

로프 는 STLPort 및 SGI STL의 일부입니다.


2
operator [] 문제는 실제로 문제가 아닙니다. const 변형은 보호 기능을 제공하며, non-const 변형은 항상 해당 시점에 CoW를 수행 할 수있는 옵션이 있습니다 (또는 정말 미쳐서 트리거하도록 페이지 폴트를 설정).
크리스토퍼 스미스

+1 문제로 이동합니다.
건배와 hth. -Alf 2014

5
std :: cow_string 클래스가 lock_buffer () 등과 함께 포함되지 않았다는 것은 어리석은 일입니다. 스레딩이 문제가 아니라는 것을 알고있는 경우가 많습니다. 실제로는 그렇지 않습니다.
Erik Aronesty 2015

나는 대안, ig 로프의 제안을 좋아합니다. 다른 대안 유형과 구현이 있는지 궁금합니다.
Voltaire

5

21.4.2 basic_string 생성자 및 할당 연산자 [string.cons]에서

basic_string(const basic_string<charT,traits,Allocator>& str);

[...]

2 효과 : basic_string표 64와 같이 클래스의 객체를 구성한다. [...]

표 64는이 (복사) 생성자를 통해 객체를 생성 한 후 다음 this->data()과 같은 값을 갖는 것을 유용하게 문서화합니다 .

첫 번째 요소가 str.data ()에 의해 가리키는 배열의 할당 된 복사본의 첫 번째 요소를 가리 킵니다.

다른 유사한 생성자에 대해서도 유사한 요구 사항이 있습니다.


+1 C ++ 11 (적어도 부분적으로)이 COW를 금지하는 방법을 설명합니다.
건배와 hth. -Alf 2014

죄송 해요, 피곤 했어요. 버퍼가 현재 공유 된 경우 .data () 호출이 COW 복사를 트리거해야한다는 것 이상을 설명하지 않습니다. 그래도 유용한 정보이므로 찬성 투표는 그대로 두었습니다.
건배와 hth. - 알프

1

이제 문자열이 연속적으로 저장되고 이제 문자열의 내부 저장소에 대한 포인터를 사용할 수 있으므로 (예 : & str [0]은 배열의 경우처럼 작동 함) 유용한 COW를 만들 수 없습니다. 이행. 너무 많은 것을 복사해야 할 것입니다. 심지어 바로 사용 operator[]또는 begin()비 const가 문자열 사본을 요구한다.


1
C ++ 11의 문자열은 연속적으로 저장 될 수 있다고 생각합니다.
mfontanini

4
과거에는 이러한 모든 상황에서 복사를해야했지만 문제가되지 않았습니다 ...
David Rodríguez-dribeas

@mfontanini 예,하지만 이전에는 없었습니다
Dirk Holsopple 2012-08-30

3
C ++ 11은 문자열이 연속적임을 보장하지만 이는 COW 문자열을 금지하는 것과 직교합니다. GCC의 COW 문자열은 연속적이므로 "유용한 COW 구현을 만들 수 없다"주장 은 가짜입니다.
Jonathan Wakely

1
@supercat, 백업 저장소 요청 (예 :를 호출 c_str())은 O (1)이어야하고 던질 수 없으며 데이터 경쟁을 도입해서는 안됩니다. 따라서 느리게 연결하는 경우 이러한 요구 사항을 충족하기가 매우 어렵습니다. 실제로 유일하게 합리적인 옵션은 항상 인접한 데이터를 저장하는 것입니다.
조나단 Wakely

1

COW basic_string는 C ++ 11 이상에서 금지됩니까?

에 관해서

C ++ 11이 COW 기반 구현을 인정하지 않는다는 것이 맞 std::string습니까?

예.

에 관해서

그렇다면이 제한은 새로운 표준 (어디)의 어딘가에 명시 적으로 명시되어 있습니까?

거의 직접적으로 COW 구현에서 문자열 데이터의O ( n ) 물리적 복사가 필요한 여러 작업에 대한 지속적인 복잡성의 요구 사항에 의해.

예를 들어, 멤버 함수의 경우

auto operator[](size_type pos) const -> const_reference;
auto operator[](size_type pos) -> reference;

… COW 구현에서 ¹ 문자열 값 공유를 해제하기 위해 문자열 데이터 복사를 트리거하는 C ++ 11 표준은

C ++ 11 §21.4.5 / 4 :

복잡성 : 일정한 시간.

… 이것은 그러한 데이터 복사를 배제하고 따라서 COW.

C ++ 03에 의해 COW 구현을 지원 하지 이러한 일정 복잡성 요구 사항을 가지고, 그리고 특정 제한 조건에 의해 호출 수 operator[](), at(), begin(), rbegin(), end(), 또는 rend()즉, 문자열 항목을 참조 무효화 참조, 포인터와 반복자에에 가능하게 발생할을 COW 데이터 복사. 이 지원은 C ++ 11에서 제거되었습니다.


COW는 C ++ 11 무효화 규칙을 통해서도 금지됩니까?

글을 쓰는 시점에 해결책으로 선택되고 크게 찬성되어 분명히 믿어지는 또 다른 답변에서 다음과 같이 주장됩니다.

COW 문자열의 경우 non-를 호출 const operator[]하려면 복사 (및 참조 무효화)가 필요합니다. 이는 위의 [C ++ 11 §21.4.1 / 6] 단락에서 허용하지 않습니다. 따라서 C ++ 11에서 COW 문자열을 갖는 것은 더 이상 합법적이지 않습니다.

이 주장은 다음 두 가지 측면에서 부정확하고 오해의 소지가 있습니다.

  • const항목 이 아닌 접근 자만 COW 데이터 복사를 트리거해야 함을 잘못 나타냅니다 .
    그러나 const항목 접근자는 클라이언트 코드가 COW 데이터 복사를 트리거 할 수있는 작업을 통해 나중에 무효화 할 수없는 참조 또는 포인터를 형성 할 수 있도록 허용하기 때문에 데이터 복사를 트리거해야합니다.
  • COW 데이터 복사로 인해 참조 무효화가 발생할 수 있다고 잘못 가정합니다.
    그러나 올바른 구현에서 COW 데이터 복사, 문자열 값 공유 해제는 무효화 될 수있는 참조가 있기 전에 수행됩니다.

올바른 C ++ 11 COW 구현이 basic_string어떻게 작동 하는지 보려면 이를 무효화하는 O (1) 요구 사항이 무시 될 때 문자열이 소유권 정책간에 전환 할 수있는 구현을 생각해보십시오. 문자열 인스턴스는 Sharable 정책으로 시작합니다. 이 정책이 활성화되면 외부 항목 참조가있을 수 없습니다. 인스턴스는 고유 정책으로 전환 할 수 있으며, .c_str()(적어도 내부 버퍼에 대한 포인터를 생성하는 경우) 호출과 같이 항목 참조가 잠재적으로 생성 될 때 그렇게해야합니다 . 값의 소유권을 공유하는 여러 인스턴스의 일반적인 경우에는 문자열 데이터 복사가 수반됩니다. 고유 정책으로 전환 한 후 인스턴스는 할당과 같은 모든 참조를 무효화하는 작업을 통해서만 다시 공유 가능으로 전환 할 수 있습니다.

따라서 COW 문자열이 배제되었다는 대답의 결론은 정확하지만 제공된 추론은 정확하지 않으며 오해의 소지가 있습니다.

이 오해의 원인이 C ++ 11의 부록 C에있는 비 규범 적 메모라고 생각합니다.

C ++ 11 §C.2.11 [diff.cpp03.strings], 약 §21.3 :

변경basic_string 사항 : 요구 사항은 더 이상 참조 카운트 문자열을 허용하지 않습니다
. 이유 : 무효화는 참조 카운트 문자열과 미묘하게 다릅니다. 이 변경은이 국제 표준의 행동 (원문)을 정규화합니다.
원래 기능에 미치는 영향 : 유효한 C ++ 2003 코드는이 국제 표준에서 다르게 실행될 수 있습니다.

여기서 근거 는 C ++ 03 특수 COW 지원을 제거하기로 결정한 주요 이유를 설명합니다 . 이 근거, 그 이유 는 표준이 COW 구현을 효과적으로 허용하지 않는 방법 이 아닙니다 . 이 표준은 O (1) 요구 사항을 통해 COW를 허용하지 않습니다.

요컨대, C ++ 11 무효화 규칙은 COW 구현을 배제하지 않습니다 std::basic_string. 그러나 그들은 g ++의 표준 라이브러리 구현 중 적어도 하나에있는 것과 같이 합리적으로 효율적인 무제한 C ++ 03 스타일 COW 구현을 배제합니다. 특별한 C ++ 03 COW 지원 const은 무효화에 대한 미묘하고 복잡한 규칙을 희생 하면서 특히 항목 접근자를 사용하여 실질적인 효율성을 허용했습니다 .

"첫 번째 호출"COW 지원을 포함하는 C ++ 03 §21.3 / 5 :

" a의 요소를 참조 참조 포인터 및 반복자 basic_string시퀀스는 그 다음 사용에 의해 무효화 될 수도 basic_string개체 :
- 비 멤버 함수의 인수로 swap()(21.3.7.8), operator>>()(21.3.7.9)와 getline()(21.3. 7.9).
—의 인수로 basic_string::swap().
— 호출 data()c_str()멤버 함수.
- 비 호출 const제외 멤버 함수 operator[](), at(), begin(), rbegin(), end(), 및 rend().
-의 형태를 제외하고 상기 용도 중 임의의 이후 insert()erase()반복자 반환 비 처음 호출 const멤버 함수 operator[](), at(), begin(), rbegin(),end(), 또는 rend().

이러한 규칙은 너무 복잡하고 미묘해서 많은 프로그래머가 정확한 요약을 제공 할 수 있을지 의심 스럽습니다. 나는 할 수 없었다.


O (1) 요구 사항이 무시되면 어떻게됩니까?

예를 들어 C ++ 11 일정 시간 요구 사항 operator[]이 무시되면 COW for basic_string는 기술적으로는 가능하지만 구현하기 어려울 수 있습니다.

COW 데이터 복사없이 문자열 내용에 액세스 할 수있는 작업은 다음과 같습니다.

  • 를 통한 연결 +.
  • 를 통해 출력 <<.
  • basic_string표준 라이브러리 함수에 인수로 사용 .

후자는 표준 라이브러리가 구현 특정 지식과 구성에 의존하도록 허용되기 때문입니다.

또한 구현은 COW 데이터 복사를 트리거하지 않고 문자열 내용에 액세스하기위한 다양한 비표준 기능을 제공 할 수 있습니다.

가장 복잡한 요인은 C ++ 11에서 basic_string항목 액세스가 데이터 복사 (문자열 데이터 공유 해제)를 트리거해야하지만 던지지 않아야한다는 것입니다 (예 : C ++ 11 §21.4.5 / 3 " Throws : Nothing."). 따라서 일반 동적 할당을 사용하여 COW 데이터 복사를위한 새 버퍼를 만들 수 없습니다. 이를 해결하는 한 가지 방법은 메모리를 실제로 할당하지 않고도 예약 할 수있는 특수 힙을 사용한 다음 문자열 값에 대한 각 논리적 참조에 필요한 양을 예약하는 것입니다. 이러한 힙에서 예약 및 예약 해제는 일정 시간 O (1) 일 수 있으며 이미 예약 한 양을 할당하면noexcept. 표준의 요구 사항을 준수하기 위해이 접근 방식을 사용하려면 고유 한 할당 자당 하나의 특별한 예약 기반 힙이 있어야합니다.


참고 :
¹ const항목 접근자는 클라이언트 코드가 데이터에 대한 참조 또는 포인터를 얻을 수 있도록 COW 데이터 복사를 트리거합니다. 이는 예를 들어 const항목 이 아닌 접근 자 에 의해 트리거되는 이후 데이터 복사에 의해 무효화되는 것이 허용되지 않습니다 .


3
" 귀하의 예제는 C ++ 11에 대한 잘못된 구현의 좋은 예입니다. 아마도 C ++ 03에 맞았을 것입니다." , 그게 예의 요점입니다 . 이전 반복기 무효화 규칙을 위반하지 않고 새 반복기 무효화 규칙을 위반하므로 C ++ 11에서는 유효하지 않기 때문에 C ++ 03에서 합법적 인 COW 문자열을 표시합니다. 그리고 그것은 또한 위의 주석에서 인용 한 진술과 모순됩니다.
조나단 Wakely

2
처음에 공유 하지 않았다면 공유 할 수 있다고했다면 나는 논쟁하지 않았을 것입니다. 무언가가 처음에 공유되었다는 것은 혼란 스러울뿐입니다. 자신과 공유 하시겠습니까? 그것은 그 단어가 의미하는 바가 아닙니다. 하지만 반복합니다. C ++ 11 반복기 무효화 규칙이 COW 문자열의 종류를 가장 확실하게 금지 할 때 실제로 사용되지 않은 가상의 COW 문자열 (허용 할 수없는 성능)을 금지하지 않는다고 주장하려는 시도 실제로 사용 된 것은 다소 학술적이고 무의미합니다.
조나단 Wakely

5
당신이 제안한 COW 문자열은 흥미롭지 만 그것이 얼마나 유용한 지 잘 모르겠습니다 . COW 문자열의 요점은 두 문자열이 기록 된 경우에만 문자열 데이터를 복사하는 것입니다. 사용자 정의 읽기 작업이 발생할 때 제안 된 구현을 복사해야합니다. 컴파일러 읽기만 알고 있더라도 여전히 복사해야합니다. 또한 고유 문자열을 복사하면 해당 문자열 데이터 (아마도 공유 가능 상태)가 복사되어 COW가 다소 무의미 해집니다. 따라서 복잡성이 보장되지 않으면 정말 엉뚱한 COW 문자열을 작성할 수 있습니다.
니콜 올가미

2
따라서 복잡성 보장이 어떤 형태 의 COW도 작성 하지 못하도록하는 것은 기술적으로 옳지 만, 진정으로 유용한 형태의 COW 문자열 을 작성하지 못하게하는 것은 [basic.string] / 5입니다 .
Nicol Bolas 2016

4
@JonathanWakely : (1) 귀하의 인용문은 문제가 아닙니다. 여기에 질문이 있습니다.“C ++ 11이 std :: string의 COW 기반 구현을 인정하지 않는다는 것이 맞습니까? 그렇다면이 제한이 새로운 표준 (어디)의 어딘가에 명시 적으로 명시되어 있습니까?” (2) std::stringO (1) 요구 사항을 무시할 때 COW 가 비효율적이라는 귀하의 의견은 귀하의 의견입니다. 공연이 뭔지는 모르겠지만, 그 주장은이 답변에 대한 어떤 관련성보다는 그 느낌, 전달하는 분위기 때문에 더 많이 제시되었다고 생각합니다.
건배와 hth. - 알프

0

나는 항상 불변의 젖소에 대해 궁금해했습니다. 일단 젖소가 만들어지면 다른 젖소의 할당을 통해서만 변경 될 수 있으므로 표준을 준수 할 것입니다.

나는 오늘 간단한 비교 테스트를 위해 그것을 시도 할 시간을 가졌다. 모든 노드가 맵의 모든 문자열 세트를 보유하고있는 문자열 / 소로 키가 지정된 크기 N의 맵 (우리는 NxN 개의 객체를 가지고 있음).

~ 300 바이트 크기의 문자열과 N = 2000 젖소는 약간 더 빠르며 메모리를 거의 사용하지 않습니다. 아래를 참조하십시오. 크기는 kbs, 런 b는 젖소입니다.

~/icow$ ./tst 2000
preparation a
run
done a: time-delta=6 mem-delta=1563276
preparation b
run
done a: time-delta=3 mem-delta=186384
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.