STL 또는 Qt 컨테이너?


185

Qt는 용기 (사용 장단점 무엇인가 QMap, QVector그들의 STL 당량 이상 등)?

Qt를 선호하는 이유는 다음과 같습니다.

  • Qt 컨테이너는 Qt의 다른 부분으로 전달 될 수 있습니다. 예를 들어,는를 채우는 데 사용될 수있는 QVariantQSettings(일부 제한 한 것처럼, 전용 QListQMap/ QHash그 키가 스트링 허용된다).

다른 것이 있습니까?

편집 : 응용 프로그램이 이미 Qt에 의존한다고 가정합니다.

답변:


135

나는 std::(w)stringSTL 컨테이너를 독점적 으로 사용 하고 Qt와 동등한 것으로 변환하거나 그로부터 변환하는 것으로 시작 했지만 이미 전환했으며 QStringQt의 컨테이너를 점점 더 많이 사용하고 있음을 알았습니다.

문자열 QString과 관련하여 훨씬 더 완벽한 기능을 제공 std::basic_string하며 완전히 유니 코드를 인식합니다. 또한 효율적인 COW 구현을 제공하므로 크게 의존합니다.

Qt의 컨테이너 :

  • 에서와 동일한 COW 구현을 제공합니다 QString. 이는 Qt의 foreach매크로 (사본 수행)를 사용하거나 메타 유형 또는 신호 및 슬롯 을 사용할 때 매우 유용 합니다.
  • STL 스타일 이터레이터 또는 Java 스타일 이터레이터를 사용할 수 있습니다
  • 스트리밍 가능 QDataStream
  • Qt의 API에서 광범위하게 사용됩니다
  • 운영 체제 전체에서 안정적으로 구현됩니다. STL 구현은 C ++ 표준을 준수해야하지만 원하는대로 자유롭게 수행 할 수 있습니다 ( std::stringCOW 논쟁 참조 ). 일부 STL 구현은 특히 나쁩니다.
  • TR1을 사용하지 않으면 사용할 수없는 해시 제공

QTL은 J. Blanchette에 의해 요약 된 STL과는 다른 철학을 가지고 있습니다 . "STL의 컨테이너가 원시 속도에 최적화 된 반면, Qt의 컨테이너 클래스는 편의성, 최소 메모리 사용 및 최소 코드 확장을 제공하도록 신중하게 설계되었습니다."
위의 링크는 QTL 구현 및 사용되는 최적화에 대한 자세한 정보를 제공합니다.


12
새로운 표준 c ++ 0x에서 COW는 거의 벗어났습니다.

16
다시 : "[...] 최소한의 메모리 사용을 제공하도록 신중하게 설계되었습니다". 마케팅을 믿지 말아야합니다. QList<double>메모리 사용을 위해 32 비트 아키텍처에서 프로파일 을 작성하십시오.
Marc Mutz-mmutz

11
"또한 효율적인 COW 구현을 제공합니다": 멀티 스레드 응용 프로그램에있어 COW는 그다지 효율적이지 않습니다 ...
Grizzly

5
@ MarcMutz-mmutz QVector대신에 프로파일을 작성하십시오 QList. QList는 객체에 포인터를 저장하도록 설계되었다는 꽤 많은 Qt 설명이 있습니다. 따라서 동적으로 생성 된이 두 항목과이 항목에 대한 포인터는에 저장됩니다 QList. QList는 벡터와 링크 된 목록 사이의 "중간"컨테이너로 설계되었습니다. 메모리 / 성능이 중요한 경우를 위해 설계되지 않았습니다.
Dmitry Sazonov

2
@ user1095108 아무 문제가 없습니다. STL을 사용하십시오. 우리 중 일부는 올바른 코드를 빠르게 작성하는 것을 선호합니다. 그것도 아무 문제가 없습니다.
weberc2 2016 년

178

질문에 대답하기가 어렵습니다. 그것은 철학적 / 주관적 논쟁으로 귀결 될 수 있습니다.

그 말은 ...

나는 "로마에있을 때 ... 로마인들이하는 것처럼"

Qt 땅에 있다면 Qt'ians처럼 코딩하십시오. 이것은 가독성 / 일관성 문제만을위한 것이 아닙니다. stl 컨테이너에 모든 것을 저장하면 어떤 일이 발생하는지 고려한 다음 모든 데이터를 Qt 함수에 전달해야합니다. 실제로 Qt 컨테이너에 물건을 복사하는 코드 묶음을 관리하고 싶습니까? 코드는 이미 Qt에 크게 의존하므로 stl 컨테이너를 사용하여 더 "표준"으로 만드는 것과는 다릅니다. 컨테이너를 유용하게 사용할 때마다 컨테이너의 요점은 무엇입니까? 해당 Qt 컨테이너에 복사해야합니까?


1
+1 당신은 완전히 옳았습니다. 그것이 제가 질문에서 설명하려고 한 것입니다 ( "Qt를 선호하는 한 가지 이유가 있습니다"). 감사합니다
Julien-L

물론 잘 말했다. QT를하고 있다면 QT를 사용하십시오! 관리자가 QT 애플리케이션을 열고 QT와 STL이 상호 교환 적으로 사용되는 것을 볼 때 "WTF"순간을 상상해보십시오. 그것은 (불필요한) 악몽이 될 수 있습니다.
It'sPete

5
@ It'sPete STL은 표준의 일부입니다. QT는 아닙니다. 표준을 사용하는 모든 코드는 "WTF"모멘트를 트리거하지 않아야합니다.
Alice

6
로마인들은 포로들을 콜로세움에 넣고 사자들과 사냥했습니다. 더 잘 알고 있다면 지역 습관을 따르지 마십시오. 그것은 로마 제국의
현대인에게 그랬던

1
@mmutz 당신은 나쁜 일처럼, 나는 그 콜로세움에서 찾은 코드를 넣고 쇼를보고 싶다
slf

65

Qt 컨테이너는 STL 컨테이너보다 제한됩니다. STL이 우수한 곳의 몇 가지 예 (이 모든 것이 과거에 부딪 쳤습니다) :

  • STL은 모든 Qt는 버전 변경되지 않습니다, 표준화 (Qt는 2 없었다 QList포인터 기반) 및 ( QValueList; Qt는 3 있었다 (가치 기반은) QPtrListQValueListQt는 4 지금 갖고 QList와 같은 모든에서 그것의 아무것도 QPtrList 또는 QValueList ).
    (. 즉, 당신은 Qt는 컨테이너를 사용하게하더라도, STL 호환 API의 하위 집합을 사용 push_back()하지 append(), front()하지 first(), ...) 모두 Qt2-> 3 Qt3-에서 Qt는 5 와서 다시 한번 이식 피하기 위해> 4 Qt 컨테이너의 변경은 코드 변경이 가장 필요한 변경 중 하나였습니다.
  • STL 양방향 컨테이너에는 모두 rbegin()/ rend()가 있으며 역 반복 대칭을 정방향 반복으로 만듭니다. 모든 Qt 컨테이너에 컨테이너가 포함되어 있지는 않기 때문에 (반복되는 컨테이너에는 해당되지 않음) 역 반복은 불필요하게 복잡합니다.
  • STL 컨테이너는 insert()다르지만 호환 가능한 반복자 유형의 범위 를 가지므로 std::copy()훨씬 덜 자주 필요합니다.
  • STL 컨테이너에는 Allocator템플릿 인수가있어 Qt (fork of required )와 비교하여 커스텀 메모리 관리가 간단합니다 (typedef 필요 ). EDIT 20171220 : C ++ 11 및 C ++ 17에 따라 할당 자 디자인의 진보로 인해 Qt가 줄어 듭니다 . 예 : John Lakos의 강연 ( 2 부 ).QLineEdits/QString/secqstring/
  • 에 해당하는 Qt는 없습니다 std::deque.
  • std::list있다 splice(). 내가 자신을 사용하는 것을 찾을 때마다 std::list필요하기 때문 splice()입니다.
  • std::stack, std::queue로 제대로, 자신의 기본 컨테이너를 집계하고 상속하지 않습니다 QStack, QQueue않습니다.
  • QSet같은 std::unordered_set것이 아닙니다 std::set.
  • QListA는 단지 이상한 .

위의 많은 것들이 Qt에서 매우 쉽게 해결할 수 있지만 Qt 의 컨테이너 라이브러리는 현재 개발 포커스가 부족한 것으로 보입니다.

EDIT 20150106 : Qt 5 컨테이너 클래스에 C ++ 11 지원을 가져 오는 데 약간의 시간을 보낸 후 작업 가치가 없다고 결정했습니다. C ++ 표준 라이브러리 구현에 적용되는 작업을 살펴보면 Qt 클래스가 결코 따라 잡지 않을 것이 분명합니다. 우리는 현재 Qt 5.4를 출시QVector 했지만 여전히 재 할당의 요소를 옮기지emplace_back()않거나 rvalue가없거나 rvalue-입니다push_back()... ... 또한 최근에QOptional클래스 템플릿을거부하고std::optional대신기다렸습니다. 마찬가지로std::unique_ptr. 트렌드가 계속되기를 바랍니다.


3
허. 인상이 아래 I이었다 QList 이었다 에 동등 std::deque. 분명히, 나는 단지 문서를 훑어 보면 안된다.
Dennis Zickefoose

QVector했다 crbeginQt는 5.6 이후 친구
바트 Louwers

@ 알렉스는 : 잘, 나는 쉽게 사람을 추가,하지만 모든 Qt는 용기를 가지고, 아직 (사용하지 않기 때문에 std::reverse_iterator깨진 이상 QHash/ QMap, 역 참조 할 때, 반환 반복자, mapped_type대신를 value_type). 고칠 수없는 것은 없지만 2015 년부터 편집 한 내용을 참조하십시오 .
Marc Mutz-mmutz

@ MarcMutz-mmutz 설명해 주셔서 감사합니다.
Bart Louwers

예를 들어 인덱스로 QVector사용 int하여 31 비트 크기 (64 비트 시스템에서도)를 제한 한다는 사실을 목록에 추가 할 가치가 있습니다 . 또한 INT_MAX1 바이트보다 큰 크기의 요소 도 저장할 수 없습니다 . 예를 들어, x86_64 Linux gcc에서 .size()가질 수 있는 가장 큰 QVector<float>것은 536870907 요소 (2²⁹-5) 였지만 std::vector<float>4294967295 요소 (2³²-1;이 RAM은 부족하여 더 이상 시도하지 않았습니다 (이 크기는 이미 16GiB)) ).
Ruslan

31

이러한 주장을 실제 측정 가능한 현상으로 나누겠습니다.

  • 더 가벼움 : Qt 컨테이너는 STL 컨테이너보다 적은 메모리를 사용합니다
  • 더 안전한 : Qt 컨테이너는 부적절하게 사용될 기회가 적습니다.
  • 더 쉬워 진 : Qt 컨테이너는 지적 부담이 적습니다.

더 쉬움

이 문맥에서 주장하는 것은 자바 스타일 반복이 STL 스타일보다 어떻게 든 "더 쉽다"는 것입니다. 따라서이 추가 인터페이스로 인해 Qt가 더 사용하기 쉽습니다.

자바 스타일 :

QListIterator<QString> i(list);
while (i.hasNext())
    qDebug() << i.next();

STL 스타일 :

QList<QString>::iterator i;
for (i = list.begin(); i != list.end(); ++i)
    qDebug << *i;

Java 반복자 스타일은 조금 작고 깨끗하다는 이점이 있습니다. 문제는 더 이상 STL 스타일이 아닙니다.

C ++ 11 STL 스타일

for( auto i = list.begin(); i != list.end(); ++i)
    qDebug << *i;

또는

C ++ 11 foreach 스타일

for (QString i : list)
    qDebug << i;

C ++ 11을 지원하지 않는 한 다른 것을 사용할 이유가 전혀없는 매우 간단합니다.

그러나 내가 가장 좋아하는 것은 다음과 같습니다.

BOOST_FOREACH(QString i, list)
{
    qDebug << i;
}

보시다시피,이 인터페이스는 이미 매끄럽고 간결하며 현대적인 인터페이스 외에 추가 인터페이스를 제외하고는 아무것도 얻지 못합니다. 이미 안정적이고 사용 가능한 인터페이스 위에 불필요한 추상화 수준을 추가 하시겠습니까? "보다 쉬운"아이디어는 아닙니다.

또한 Qt foreach 및 Java 인터페이스는 오버 헤드를 추가합니다. 그것들은 구조를 복사하고 불필요한 간접적 인 수준을 제공합니다. 이처럼 보이지 않을 수도 있지만 왜 그렇게 간단하지 않은 인터페이스를 제공하기 위해 오버 헤드 계층을 추가합니까? java에는 연산자 오버로딩이 없기 때문에 Java에는이 인터페이스가 있습니다. C ++는 않습니다.

더 안전한

Qt가 제공하는 정당성은 암시 적 공유 문제이며 암시 적이거나 문제가 아닙니다. 그러나 공유는 포함됩니다.

QVector<int> a, b;
a.resize(100000); // make a big vector filled with 0.

QVector<int>::iterator i = a.begin();
// WRONG way of using the iterator i:
b = a;
/*
Now we should be careful with iterator i since it will point to shared data
If we do *i = 4 then we would change the shared instance (both vectors)
The behavior differs from STL containers. Avoid doing such things in Qt.
*/

첫째, 이것은 암시 적이 지 않습니다. 한 벡터를 다른 벡터에 명시 적으로 할당하고 있습니다. STL 반복자 사양은 반복자가 컨테이너에 속한다는 것을 명확하게 나타내므로 b와 a 사이에 공유 컨테이너를 명확하게 소개했습니다. 둘째, 이것은 문제가되지 않습니다. 반복자 스펙의 모든 규칙을 따르는 한 절대로 아무 문제가 없습니다. 문제가있는 유일한 시간은 다음과 같습니다.

b.clear(); // Now the iterator i is completely invalid.

Qt는이 시나리오에서 문제가 발생하는 것과 같은 것을 의미하는 것처럼 이것을 지정합니다. 그렇지 않습니다. 이터레이터는 무효화되고 여러 분리 된 영역에서 액세스 할 수있는 것과 마찬가지로 이것이 작동하는 방식입니다. 실제로 이것은 Qt의 Java 스타일 반복자와 함께 쉽게 발생합니다. 암시 적 공유에 크게 의존하기 때문입니다. 이는 여기 및 기타 여러 영역 에서 설명한 반 패턴 입니다. 이 "최적화"가 멀티 스레딩으로 점점 더 이동하는 프레임 워크에서 사용되는 것은 특히 이상해 보이지만, 그것은 당신을위한 마케팅입니다.

거룻배

이것은 조금 까다 롭습니다. 쓰기시 복사 및 암시 적 공유 및 성장 전략을 사용하면 컨테이너가 특정 시간에 사용할 메모리 양을 실제로 보장하기가 매우 어렵습니다. 이것은 강력한 알고리즘 보장을 제공하는 STL과 다릅니다.

우리 는 벡터의 최소 낭비 공간이 벡터 길이의 제곱근이라는 것을 알고 있지만 Qt에서는 이것을 구현할 방법이없는 것 같습니다. 그들이 지원하는 다양한 "최적화"는이 중요한 공간 절약 기능을 배제 할 것입니다. STL은이 기능을 필요로하지 않으며 (이는 대부분 두 배의 성장을 사용하므로 더 낭비입니다) 필요한 경우 최소한이 기능을 구현할 수 있다는 점에 유의해야합니다.

XOr 연결을 사용하여 사용 된 공간을 크게 줄일 수있는 이중 연결 목록도 마찬가지입니다. 다시 말하지만, 이것은 성장과 COW에 대한 요구로 인해 Qt에서는 불가능합니다.

COW는 실제로 더 가벼운 것을 만들 수 있지만 boost 에서 지원하는 것과 같은 Intrusive Containers도 가능 하며 Qt는 이전 버전에서 자주 사용했지만 더 이상 사용하기 어렵고 안전하지 않으며 부담을 가하기 때문에 더 이상 사용되지 않습니다. 프로그래머에. COW는 훨씬 덜 관입적인 솔루션이지만 위에 제시된 이유로 매력이 없습니다.

메모리 비용이 같거나 Qt의 컨테이너보다 적은 STL 컨테이너를 사용할 수없는 이유는 없으며, 주어진 시간에 얼마나 많은 메모리를 낭비하는지 실제로 알 수 있다는 이점이 있습니다. 불행히도, 원시 메모리 사용량에서 두 ​​가지를 비교하는 것은 불가능합니다. 그러한 벤치 마크는 사용 사례마다 크게 다른 결과를 보여 주므로 STL이 수정하도록 설계된 정확한 종류의 문제입니다.

결론적으로

복사 비용을 부과하지 않고 가능한 경우 Qt 컨테이너를 사용하지 말고 가능하면 랩퍼 또는 새 구문을 통해 STL 유형 반복을 사용하십시오.


4
당신의 요점은 대부분 유효하지만 거기에 잘못된 정보가 있습니다. Adding an unnecessary level of abstraction on top of an already stable and usable interface? Not my idea of "easier".Qt의 Java 스타일 반복자는 C ++ 11에 추가되지 않았습니다. 그들은 그것을 앞선다. 어쨌든 Qt foreach(QString elem, list)는 C ++ 11의 foreach 또는 BOOST_FOREACH처럼 쉽고 C ++ 11 이전 호환 컴파일러와 함께 작동합니다.
weberc2

@ weberc2 당신은 혼란스러워합니다. Qt의 Java 스타일 이터레이터는 C ++ (C ++ 11 아님) 이터레이터 위에 추가됩니다. 인터페이스를 부 풀리는 추가 추상화 계층 (및 불필요한 계층)으로 쉽지 않습니다. 그리고 fort for for Qt는 BOOST_FOREACH만큼 쉽지는 않습니다. 특히 안전하지 않고 동일한 지원 범위를 갖지 않기 때문입니다 (BOOST_FOREACH는 QT에서 C +를 요구하는 모든 C ++ 버전에 대해 모든 범위에 적용 할 수 있음) +03 규정 준수). 모든 비용으로 QT의 foreach를 피해야합니다.
Alice

So, as we can see, this interface gains us nothing except an additional interface, *on top of* an already sleek, streamlined, and modern interface. Adding an unnecessary level of abstraction on top of an already stable and usable interface? Not my idea of "easier".(강조 광산) 당신은 우리에게 foreach의 C ++ 11과 BOOST 버전을 보여 주 자마자 Qt 버전이 AFAICT가 아닌 두 가지 중 하나에서 만들어진 것처럼 들리도록 말했습니다. 나는 그것이 당신이 의도 한 것이 아니라고 확신하지만 그것이 그렇게되는 방식입니다. 따라서 "오해의 소지가있는 정보".
weberc2 2016 년

It's an additional layer of abstraction (and an unnecessary one) that bloats the interface, which is not easier.당신이 비교하는 내용이 여전히 명확하지 않습니다. C ++ 03 이터레이터? C ++ 11 반복자? BOOST_FOREACH? 무엇보다도?
weberc2 2016 년

1
나는 단지 당신이 말하는 어떤 반복 방법에 대해 매우 모호합니다. 나는 당신이 명확하다고 생각하고 당신의 언어는 합리적이라고 생각하지만, 명시를 거부하는 것은 이상하게 보입니다. 동의하지 않는 것에 동의합니다.
weberc2

23

STL 컨테이너 :

  • 성능 보장
  • 성능을 보장하는 STL 알고리즘에 사용할 수 있습니다
  • Boost와 같은 타사 C ++ 라이브러리에서 활용할 수 있습니다.
  • 표준이며 독점 솔루션보다 오래 지속될 가능성이 있음
  • 알고리즘 및 데이터 구조의 일반적인 프로그래밍을 장려하십시오. STL을 준수하는 새로운 알고리즘 및 데이터 구조를 작성하면 STL이 이미 제공 한 것을 무료로 이용할 수 있습니다.

5
STL 지원 (기본값)으로 Qt를 컴파일하는 경우 표준을 제외한 위의 모든 사항은 QTL에도 적용됩니다. STL 지원에는 반복자 함수, 컨테이너 typedef (const_iterator 등), 변환 함수 (STL로 /부터)가 포함됩니다.
RPG

2
Qt는 독점적이지 않습니다
txwikinger

3
@rpg 거의 모든 것이 QTL에 해당되지 않습니다. QTL은 강력한 성능 보증을 제공하지 않으며 (과거에 쉽게 중단되었으므로) STL을 준수하지 않으며 (역방향이 아니므로 많은 부스트에서 사용할 수 없음) 표준이 아니며 (버전간에 지속적으로 변경됨) 일반 프로그래밍을 권장하지 않습니다 (예 : 할당 자에 대한 템플릿 인수가 없음).
Alice

15

Qt 컨테이너는 COW (Copy On Write) 관용구를 사용합니다.


2
하나는, 성능 및 자원에 상당한 이점이 될 수있다
RedGlyph

32
또는 중대한 단점 일 수 있습니다. gotw.ca/publications/optimizations.htm
Kaz Dragon

3
: 원자 refcount는 꽤 잘 지낼 것 같다 labs.trolltech.com/blogs/2006/10/16/...
롤 플레잉

STL 컨테이너는 성능 보증 및 사양을 충족하는 모든 관용구를 자유롭게 사용할 수 있습니다. COW는 C ++ 11 / C ++ 14 STL에서도 유효합니다.
Alice

1
@Alice COW는 거의 모든 경우에 표준의 복잡성과 반복자 유효성을 보장하므로 대부분의 경우 올바른 구현이 아닙니다. COW로 구현할 수있는 몇 가지 클래스 중 하나는 std::basic_string표준이며 C ++ 11로 조치를 취해이를 부적합하게 만들었습니다.
Tiago Gomes

9

주요 문제 중 하나는 Qt의 API가 Qt의 컨테이너에 데이터를 제공 할 것을 기대한다는 것입니다. 따라서 Qt 컨테이너를 앞뒤로 변환하지 않고 간단히 Qt 컨테이너를 사용할 수도 있습니다.

또한 이미 Qt 컨테이너를 사용하고 있다면 STL 헤더 파일을 포함하지 않고 STL 라이브러리에 링크 할 필요가 없으므로 독점적으로 사용하는 것이 약간 더 좋습니다. 그러나 툴체인에 따라 어쨌든 발생할 수 있습니다. 순전히 디자인 관점에서 일관성은 일반적으로 좋은 것입니다.


1
Qt와의 인터페이스가 일반적으로 크게 과대 평가되는 경우를 제외하고 STL을 사용하는 실제 응용 프로그램에서 STL과 Qt 컨테이너 간의 "이전 / 전환"비율 대부분의 경우 프레젠테이션 레이어 (Qt를 사용하는)에서오고 오는 std :: transform을 수행하면 컨테이너 스위치가 무료로 제공됩니다. 관심있는 당사자는 projects.kde.org/projects/kde/kdepim/repository/revisions/… 를 탐색 하여 직접 확인할 수 있습니다.
Marc Mutz-mmutz

8

작업중인 데이터가 주로 Qt 기반 UI를 구동하는 데 사용되는 경우 Qt 컨테이너를 사용하십시오.

데이터가 주로 앱에서 내부적으로 사용되며 Qt에서 이식되지 않을 가능성이 높으면 성능 문제가 발생하지 않으면 Qt 컨테이너를 사용하십시오.

데이터가 주로 STL 컨테이너에 대해서만 알고있는 다른 라이브러리와 함께 사용되는 경우 STL 컨테이너를 사용하십시오. 이러한 상황이 발생하면 무엇을하든 컨테이너 유형간에 많은 양의 포트를주고받을 것이기 때문에 문제가 발생합니다.


7

COW 차이 외에도 STL 컨테이너는 다양한 플랫폼에서 훨씬 더 광범위하게 지원됩니다. Qt는 작업을 "주류"플랫폼으로 제한하는 경우 이식성이 충분하지만 STL은 다른 많은 모호한 플랫폼 (예 : Texas Instruments의 DSP)에서도 사용할 수 있습니다.

STL은 단일 회사가 제어하는 ​​것이 아니라 표준이기 때문에 일반적으로 STL 코드를 쉽게 읽고 이해하고 수정할 수있는 더 많은 프로그래머와 더 많은 리소스 (책, 온라인 포럼, 회의 등)를 지원하는 프로그래머가 있습니다. Qt보다 있습니다. 그렇기 때문에 Qt에서 부끄러워해야한다는 것은 아닙니다. 단지 다른 모든 것들이 동일하다면 STL을 기본값으로 설정해야하지만 물론 모든 것이 거의 동일하지 않으므로 자신의 상황에서 가장 적합한 것을 결정해야합니다.

AlexKR의 답변과 관련하여 : STL 성능은 한계 내에서 보장되지만, 주어진 구현은 플랫폼 종속적 세부 사항을 사용 하여 STL 속도높일 수 있습니다. 따라서 이러한 의미에서 플랫폼마다 다른 결과를 얻을 수 있지만 명시 적 보증 (모듈로 버그)보다 느리게 진행되지는 않습니다.


9
첫 번째 요점과 관련하여 OP는 이미 Qt를 사용하는 프로젝트를 언급하고 있으므로 이미 "주류"플랫폼으로 제한되어 있다고 가정합니다. 누군가 컨테이너 클래스를 위해 Qt와 같은 무거운 라이브러리를 가져올 가능성은 거의 없습니다.
ThisSuitIsBlackNot

4

내 5 센트 : Qt 컨테이너는 다른 플랫폼에서 비슷하게 작동해야합니다. STL 컨테이너는 STL 구현에 의존합니다. 다른 성능 결과가 나타날 수 있습니다.

편집 : STL이 "느리다"고 말하지는 않지만 다양한 구현 세부 사항의 영향을 지적합니다. 이것을
확인한 다음 어쩌면 .
그리고 그것은 STL의 실제 문제가 아닙니다. 분명히 성능에 큰 차이가 있다면 STL을 사용하는 코드에 문제가있는 것입니다.


STL 컨테이너는 구현에 관계없이 모두 비슷합니다. 연속 된 메모리 블록에 있어야하므로 장면 뒤의 목록처럼 벡터를 구현할 수 없습니다. STL은 일반적으로 모든 주요 플랫폼에서 크게 최적화됩니다.
Yacoby

1
STL이 약속하는 방식을 고수한다면 (STL이 구현되는 방식을 가정하는 대신) STL을 사용하는 플랫폼간에 문제가 발생하지 않습니다. Qt와 동일합니다.
Michael Kohne

이것은 사실과 정반대입니다. STL 컨테이너는 모든 플랫폼에서 항상 동일하게 작동합니다. 그렇지 않으면 STL이 아닙니다. 그러나 QT는 버전마다 성능을 크게 변경하므로 QT4.8이 아닌 QT4.0이있는 플랫폼에서는 심각한 변경이 발생할 수 있습니다.
Alice

1
매우 다른 두 가지 유형의 성능을 혼동하고 있습니다. 알고리즘 성능 및 실제 계산 성능. 모든 STL 구현은 동일한 알고리즘 성능을 보장합니다. 벡터가 요소를 인덱싱하는 데 log (n) 시간이 걸리면 STL 벡터가 아닙니다. 귀하의 링크는이 계산에서 의미가없는 실제 계산 성능을 가리 킵니다. QT는 버전간에 알고리즘을 변경하고 다른 플랫폼에서 동일한 C ++는 다른 성능을 얻습니다. 이것은 내 경험상 STL 성능의 차이보다 훨씬 가단합니다.
Alice

3

Qt를 사용하는 방식에 달려 있다고 생각합니다. 제품 전체에서 사용하는 경우 Qt 컨테이너를 사용하는 것이 합리적입니다. UI 부분에만 포함 된 경우 C ++ 표준 컨테이너를 사용하는 것이 좋습니다.


3

나는 STL이 훌륭한 소프트웨어라고 생각하지만 KDE 또는 Qt 관련 프로그래밍을 수행하려면 Qt가 갈 길입니다. 또한 사용중인 컴파일러에 따라 다르지만 GCC STL은 꽤 잘 작동하지만 SUN Studio CC라고 말하면 STL 자체가 아닌 컴파일러 때문에 STL이 두통을 일으킬 가능성이 큽니다. 이 경우 컴파일러가 머리를 아프게하므로 Qt를 사용하여 문제를 해결하십시오. 내 2 센트 만 ...


3

QVector에는 (때로는) 큰 제한이 있습니다. int 바이트의 메모리 만 할당 할 수 있습니다 (한도는 요소 수가 아닌 바이트 단위 임). 이는 QVector로 ~ 2GB보다 큰 연속 메모리 블록을 할당하려고하면 충돌이 발생한다는 것을 의미합니다. 이것은 Qt 4와 5에서 발생합니다. std :: vector에는 이러한 제한이 없습니다.


0

STL 컨테이너를 사용해야하는 주된 이유는 매우 큰 컨테이너에서 메모리를 재사용하기 위해 사용자 지정 할당자가 필요한 경우입니다. 예를 들어 1000000 개의 항목 (키 / 값 쌍)을 저장하는 QMap이 있다고 가정하십시오. Qt에서는 정확히 1000000 백만 할당 ( new호출) 을 의미합니다 . STL에서는 항상 모든 메모리를 한 번에 내부적으로 할당하고 맵이 채워질 때 각 항목에 할당하는 사용자 지정 할당자를 만들 수 있습니다.

필자는 비즈니스 로직에서 성능 결정 알고리즘을 작성할 때 STL 컨테이너를 사용하고 결과가 필요할 경우 UI 컨트롤 및 폼에 의해 표시 될 준비가되면이를 Qt 컨테이너로 다시 변환하는 것이 좋습니다.


아니 여기에 QTL을 방어하려고하지만, 당신은 수있는 전문 QMapNode<K,V>당신을 위해 K, V당신의 자신의를 제공하기 위해 operator new.
Marc Mutz-mmutz
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.