É prático abandonar o STL no desenvolvimento de C ++? [fechadas]


19

Eu sei que em algumas áreas (indústria de jogos, por exemplo), STL não é recomendado. Então, minha pergunta é: é realmente uma boa prática não usar STL em alguns casos? Se sim, quais são os maiores motivos para não usar o STL moderno do C ++?



alguns de meus colegas argumentam que, o iterador torna a depuração mais difícil, porque às vezes não é fácil intervir, e isso também se aplica ao lambda. Qual a sua resposta?
precisa saber é o seguinte

Quanto a ignorar coisas durante a depuração, consulte, por exemplo: stackoverflow.com/questions/2062881/…
Martin Ba

Esta parece ser uma boa pergunta. Talvez alguém possa adicionar "Por que um projeto escolheria não usar o STL?"
Matthew James Briggs

Respostas:


25
  • Só consigo pensar em um motivo válido e é realmente raro: tempo real difícil. Muitas coisas na biblioteca padrão alocam memória internamente e isso não é determinístico o suficiente para aplicativos difíceis em tempo real; portanto, elas devem ser evitadas. Esses aplicativos geralmente são bastante simples, embora levem um tempo desproporcional para serem desenvolvidos devido à rigorosa revisão e teste.

  • Posso pensar em um motivo inválido, mas muito comum: desenvolvedores que não entendem a complexidade computacional, usam mal o STL e depois culpam a biblioteca.

    O STL geralmente é mais rápido em tempo de execução do que as soluções no estilo C com ponteiros de retorno de chamada ou soluções baseadas em polimorfismo com métodos virtuais ( consulte também a palestra de abertura de Bjarne Stroustrup ). No entanto, quando o desenvolvedor não entende as especificações de complexidade fornecidas e utiliza mal a biblioteca, criando algo como vetor de vetores de alguns objetos complexos (no C ++ 11, porém, isso não é mais um problema!), Causa um problema de desempenho e se defende. com "você vê, os vetores são bastante lentos", pode causar uma percepção de que a biblioteca padrão é lenta. E uma vez que os gerentes tenham essa percepção, ela poderá viver muito tempo na organização.

  • Obviamente, você não pode usar nada que a plataforma que você está direcionando não suporta. No entanto, atualmente estamos segmentando quatro plataformas móveis mais comuns (Android, iOS, Bada e WinCE antigo) e usamos a biblioteca padrão e algumas partes do Boost em todas elas.

    Grande parte da biblioteca padrão costumava não ser suportada pela Microsoft no início do WinCE (os iostreams IIRC eram lançados apenas com o Visual Studio 2005), mas era possível usar o STLport muito antes disso. E você pode conseguir isso para compilar qualquer coisa. Então, eu chamaria esse motivo de inválido também.

    Além disso, por um longo tempo, não é "STL", mas sim a Biblioteca Padrão ANSI C ++. É definido pelo mesmo documento padrão que define o próprio idioma. Qualquer coisa que não o suporte realmente não merece ser chamado de C ++.


6
O primeiro argumento (em tempo real) não é específico para as partes STL da Biblioteca Padrão. sprintffrequentemente aloca memória também. Nas plataformas em tempo real, as funções padrão da biblioteca também têm limites determinísticos. Isso dificulta as implementações de C ++ em tempo real: você teria que desenvolver cuidadosamente toda uma biblioteca padrão de C ++, que é mais trabalhosa do que apenas a pequena biblioteca padrão de C ++.
MSalters

@MSalters: Claro, muitas coisas não podem ser usadas sob requisitos em tempo real. Mesmo alguns recursos de linguagem, como exceções, não podem. Ainda assim, o C ++ é uma ótima linguagem para esses sistemas, porque pode combinar desempenho e controle preciso com fortes salvaguardas (o RAII é o recurso mais importante para isso).
Jan Hudec

@JanHudec: De fato, é por isso que as partes STL são necessárias apenas para implementações "hospedadas" de C ++.
MSalters

7

Eu estou usando STL e impulsionar por muitos anos já. Se eu quisesse abandoná-lo e usar minhas ferramentas personalizadas, a motivação seria:

  1. Redução do tempo de compilação (75%). Apenas incluir iostreams pode adicionar 1 milhão de linhas de código ao seu módulo. Sim, cabeçalhos pré-compilados ajudam muito, mas ainda retarda muito a compilação em grandes projetos. A longo prazo, perde muito tempo de quem trabalha nele.
  2. Atuação. (25%) O STL é escrito para funcionar geralmente, mas você pode otimizar suas estruturas para funcionarem exatamente como você deseja. Por exemplo, você pode ter estruturas de dados com milhões de cadeias curtas. Pode ser muito mais rápido usar a classe de string personalizada com base no princípio de boost :: small_vector (vetor estático local pequeno de dados, alocação dinâmica apenas para strings maiores), esse tipo de alteração pode fazer com que seções críticas do código funcionem muitas vezes mais rapidamente.

1
O SSO já é comum.
Deduplicator

para a posteridade: SSO -> otimização de pequenas cadeias, ou seja, a maioria das implementações std :: string mantém pequenas cadeias na pilha e alterna para o heap, se necessário
azul

O tempo de compilação é grande
user1754322

4

Há um grande motivo válido para não usar a biblioteca de modelos padrão do C ++: uma de suas plataformas de destino não possui uma implementação totalmente em conformidade (ou nenhuma implementação) e você sabe que ela não estará recebendo uma nos próximos anos.


3
Aka "não use quando você não o tem", o que realmente faz sentido. :)
Xeo 16/08/12

4
Como a biblioteca padrão C ++ 03 foi projetada para ser implementada apenas em termos da biblioteca ANSI C89, existe alguma plataforma em que você não possa obter pelo menos o STLPort ?
Jan Hudec

@ JanHudec Eu acredito que existem plataformas sem STL porque elas não têm memória suficiente para lidar com tudo. Geralmente, também estão faltando outras funcionalidades do C ++ (por exemplo, exceções).
Sulthan

2
@Sulthan: Para os microcontroladores, eu meio que entendo, mas esses se enquadram na categoria "hard realtime" normalmente. Para qualquer outra coisa, isso é principalmente preconceitos, porque o STL geralmente é tão eficiente em termos de memória e desempenho quanto o código artesanal. Muitos inlining podem causar um binário maior, mas isso pode até ser evitado por uma implementação cuidadosa a algum custo de desempenho (que uma solução artesanal também teria). As exceções ausentes também são preconceito ou preguiça, porque é preciso esforço para definir e implementar a exceção ABI.
Jan Hudec

4

Eu não sei sobre complexidade (eficiência de implementação), mas estou usando contêineres e strings Qt extensivamente em vez dos std e eles funcionam bem. Também acho a implementação Qt de conjuntos e listas mais fácil de usar.

Portanto, pode ser prático abandonar o STL se você puder usar outra biblioteca que atenda às suas necessidades.


2
os equivalentes de Qt foram criados há muito tempo, quando não havia implementações de STL que fossem a) disponíveis ou b) boas. Essa é a única razão pela qual eles ainda são usados, nada contra o STL de hoje.
Gbjbaanb

1
@ Giorgio: o problema está em aplicações complexas, nas quais você combina várias bibliotecas. Os contêineres da STL, por padrão, formam uma língua franca . Mais precisamente, são as convenções deles. O exemplo mais conhecido é o Boost. Pode trabalhar em contêineres STL. ele também pode trabalhar em recipientes Qt, mas apenas porque Qt tem segue as convenções STL - por exemploQList<T>::iterator
MSalters

3
Não diminuí a votação, mas vejo um motivo: não responde à pergunta. Você disse que há coisas para usar em vez de STL, tudo bem, mas essa não é uma razão para evitar STL. Além de qualquer motivo para evitar o STL, provavelmente se aplica ao Qt, MFC e outras bibliotecas desse tipo, ou até mais.
Jan Hudec

3
@NoOne: Achamos que você está acostumado a andar de camelcase, não em casos de cobras, mas isso não torna o último pior. E dos três nomes de funções que você critica, o primeiro é perfeitamente descritivo para qualquer pessoa que tenha algo a ver com c-strings, e os outros dois são herdados de C, não os discutem.
Deduplicator

1
@NoOne: Como eu disse, entendo totalmente que você está mais confortável com o CamelCase.
Deduplicator

3

Patrick mencionou o motivo de não usar todo o STL, a saber, que sua (s) plataforma (s) não possui um.

Em suma, acho que a questão está faltando. Principalmente não é uma decisão do tipo tudo ou nada, mas uma escolha. Você pode optar por usar os contêineres e algoritmos, mas decide usar algo fora do Lib Std para strings e E / S.


3

Não é prático, a menos que haja uma forte razão para fazê-lo. Alguns dos motivos pelos quais posso pensar incluem apenas a implementação parcial ou inexistente do STL (ou qualquer outra parte da biblioteca padrão) ou uma limitação de recursos (memória, velocidade da CPU, armazenamento, ...) que você precisa contornar rolando suas próprias ferramentas que aderem ao que você precisa realizar.

Na indústria de jogos, a maioria dos estúdios (até um pouco menores) tem suas bibliotecas e implementações internas de muitas partes da biblioteca padrão, altamente adaptadas para a plataforma de destino e, em alguns casos, como alvo do engnie ou mesmo do próprio jogo. Simplificando, ao desenvolver um jogo para consoles, o hardware é muito limitado pelos padrões atuais. Existem milhares e milhares de linhas de montagem artesanal por um motivo. É muito importante minimizar todos os tipos de pegadas de recursos no seu código, para que o jogo corra mais rápido, o que permite mais conteúdo no mundo do jogo (ou um mundo maior, por exemplo), o que, esperançosamente, resulta em um produto melhor.

"Todo jogo bem-sucedido começa lançando sua própria implementação de lista vinculada".


1
Eu imagino que todo jogo bem-sucedido começa escrevendo código usando a biblioteca padrão e otimizando o código apenas quando o jogo tiver sido extensivamente elaborado. A otimização antes de ter dados de criação de perfil informando o que precisa de otimização é inútil.
Cromulent

Verdade. A última frase foi apenas uma brincadeira com a maneira "antiga" de escrever jogos no início dos anos 90, quando o C ++ não era tão amplamente implantado e o assembly + C era o caminho a seguir. Talvez eu devesse ter deixado mais claro. No entanto, aplica-se bem à indústria de jogos em consoles, a maioria dos algoritmos e estruturas de dados são escritos à mão por padrão, porque cada byte e ciclo conta (sim, mesmo à custa de manutenção / portabilidade / qualquer outra coisa).
Zxcdw 16/08/12

2
Deve-se dizer que é uma experiência antiga. O otimizador moderno geralmente gera melhor montagem a partir de um código simples de manutenção do que o programador fará manualmente e os modelos genéricos, como no STL ou no Boost, geralmente se alinham a um código tão eficiente quanto a caixa especial de tudo à mão. Mas há muito código iniciado em épocas em que esse não era o caso e muitas pessoas que aprenderam o ofício naqueles dias e continuam trabalhando dessa maneira, mesmo que isso não faça mais sentido.
Jan Hudec

2
@JanHudec O problema é que as implementações (e comportamentos também são verdadeiros) precisam ser muito personalizadas para a tarefa. Você simplesmente não pode poupar algumas dúzias de bytes aqui e ali (localidade de referência em ruínas), soltar algumas ramificações para validar entradas (erros de previsão de ramificações e falhas no cache de instruções) e assumir que o compilador sabe como vetorizar suas estruturas de dados otimamente para tirar proveito do SIMD (não será, ou pelo menos você precisará verificar se o que ele tenta está correto). É claro que escrever software em tempo real em um PC não é tão rigoroso, você sempre pode usar uma CPU mais rápida. Não nos consoles.
Zxcdw 17/08/12
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.