5 pontos por GN⁺ 2023-07-04 | 1 comentários | Compartilhar no WhatsApp
  • A edição online de Data-Oriented Design é um material disponibilizado para que leitores interessados em aprender design orientado a dados possam consultar gratuitamente o conteúdo essencial
  • Embora alguns capítulos não essenciais do livro completo tenham sido omitidos, ela é estruturada em torno do conteúdo indispensável para o aprendizado
  • Como o documento foi convertido automaticamente de LaTeX para HTML, pode haver erros de formatação, imagens quebradas e listagens de código-fonte corrompidas
  • Para listagens de código-fonte corrompidas, o código de referência pode ser consultado em um repositório no GitHub separado
  • Comprar o livro impresso é uma forma de lê-lo em um formato melhor e também ajuda a manter a edição online para leitores que não podem comprá-lo

Natureza da edição online

  • Data-Oriented Design é oferecido como uma edição online gratuita e abreviada sobre design orientado a dados
  • Alguns capítulos não essenciais foram excluídos, mas o fluxo central necessário como material de estudo está incluído
  • É voltado a leitores que desejam aprender uma abordagem de design que coloca os próprios dados no centro

Qualidade da conversão do documento e referência de código

  • O documento online foi gerado automaticamente, então parte da formatação pode estar estranha
  • Como as ferramentas de conversão de LaTeX para HTML não são perfeitas, imagens ou listagens de código-fonte podem estar quebradas
  • Caso uma listagem de código-fonte esteja quebrada, o código referenciado pode ser encontrado no GitHub

Livro impresso e feedback

  • O livro impresso pode ser lido em um formato melhor do que a edição online
  • Comprar o livro impresso ajuda a manter a versão online disponível para leitores que não têm condições de comprá-lo
  • Feedback pode ser enviado para support@dataorienteddesign.com

1 comentários

 
GN⁺ 2023-07-04
Opiniões do Hacker News
  • Um dos melhores conselhos que já recebi para escrever código combinável e de alto desempenho foi: “estruturas de arrays, não arrays de estruturas”, e este texto transmite muito dessa mesma ideia
    Pelo visto, a arquitetura entidade-componente funciona bem não só em jogos, mas também em aplicações corporativas
    Só que muitos desenvolvedores de empresas estão presos ao modelo CRUD de armazenamento de registros, então têm dificuldade para pensar em colunas em vez de linhas, e muitas vezes não é natural imaginar colocar o ID da entidade na tabela published em vez de mudar o campo booleano published para true
    Ainda assim, depois que você percebe como essa abordagem se expande de forma tão facilmente polimórfica, dá vontade de usá-la para todos os dados. Aí surgem novas oportunidades de reutilizar dados de componentes de forma cruzada, e você começa a se perguntar por que é permitido que uma interface de rede tenha aniversário, que uma fatura tenha um endereço IPv6 anexado, que um gato entre no pool de DHCP e que limegreen seja excluído e custe 5 dólares às terças-feiras — e essa é metade da diversão
    Não concordo com a afirmação de que isso é totalmente incompatível com orientação a objetos. Já usei essa abordagem até com Active Record do Ruby, e funcionou bem mesmo em áreas que normalmente não são associadas a “alto desempenho”. Funcionou especialmente bem porque o sistema de objetos do Ruby é mais próximo de Smalltalk do que de C++/Java e, por isso, favorece fortemente a composição em vez da herança

    • Não entra em conflito com os mecanismos da orientação a objetos, mas exige que o programador mude a forma como enxerga o problema
      Em linguagens orientadas a objetos, normalmente você se concentra em um “alvo sobre o qual quer pensar” — como usuário, post de blog ou transação financeira —, implementa isso de forma separada do resto e depois pensa em quais métodos expor para outras partes do sistema, ocultando os dados. O conceito de encapsulamento é muito forte
      Já no design orientado a dados, é mais comum que dados de domínios diferentes estejam acessíveis, e que os subsistemas escolham o que precisam para realizar seu trabalho. Java ou Ruby não impedem isso, mas para o programador existe claramente uma barreira psicológica
    • O artigo da Wikipedia sobre “Array of Structure (AoS) and Structure of Arrays (SoA)” explica o equilíbrio entre SoA do lado da performance e AoS do lado da intuitividade e do suporte da linguagem: https://en.wikipedia.org/wiki/AoS_and_SoA
      Também fala de suporte de software que permite acessar SoA como se fosse AoS, como os data frames do R, o Pandas do Python e o DataFrames.jl do Julia
    • No mundo dos dados, “estruturas de arrays” corresponde a índices colunares como Snowflake ou OLAP, e “arrays de estruturas” corresponde a bancos de dados relacionais que usam índices baseados em páginas e linhas
      Gosto muito do Snowflake e acho que ele vai tomar o almoço dos concorrentes. Também é interessante que o Snowflake “suporte” chaves estrangeiras, mas não as imponha. Em outras palavras, Snowflake é o tanto de “NoSQL” que eu consigo tolerar
    • Acho que existem dois tipos de design orientado a dados. Um deles é, como foi dito antes, a abordagem de “estruturas de arrays, não arrays de estruturas”
      O outro é abrir mão do encapsulamento, separar os dados dos métodos que lidam com eles e modelar toda a aplicação em torno de como os dados fluem, para que seja mais fácil entender e modificar. Para maior precisão, é possível usar estruturas de dados imutáveis e funções puras
    • Já tentei introduzir ECS em aplicações que não eram jogos, e uma empresa financeira em Londres adotou esse conselho para gerenciar a complexidade do sistema. Funcionou muito bem
      Para quem tiver curiosidade, aqui vai uma introdução bem curta a ECS: https://dev.to/ovid/the-unknown-design-pattern-1l64
  • “O layout dos dados é definido por uma única interpretação, vinda de uma única perspectiva?” pode ser a pergunta mais importante na hora de escolher tecnologia e arquitetura. Normalmente, para responder isso, é preciso conversar com o negócio e com os clientes
    Se você tem certeza de que existe exatamente uma única “visão” válida dos dados para uso em todo o sistema, então faz sentido gravar isso no código. Se houver a menor incerteza, um modelo em estilo relacional provavelmente será mais adequado. Muitas empresas, quando percebem a teoria dos jogos desse problema, acabam chegando em SQL
    Todo mundo se pergunta por que parece que todos se afastaram de um único grande banco de dados SQL. Existem casos extremos de “escala web” que ameaçam a escalabilidade vertical das escritas, mas acho que a maioria das empresas, inclusive as da F100, nem chega perto disso

    • Em uma antiga empresa de tecnologia da F100, recebi a diretriz de proibição de RDBMS sem aprovação explícita
      Isso não tinha relação com a melhor forma de modelar um determinado conjunto de dados nem com o melhor desempenho; era inteiramente por causa da flexibilidade de esquema e do histórico de incidentes causados por falhas em migrações de esquema. Em projetos NoSQL, esse problema não acontecia, e as vantagens oferecidas por bancos SQL não compensavam o grande benefício do NoSQL sem esquema rígido
      Claro, se você usar mal um armazenamento chave-valor, desempenho e custo podem sair muito do controle. Em plataformas de nuvem como o DynamoDB, já vi muitos casos em que a estruturação incorreta dos dados levou a uma enxurrada de scans e a uma explosão de custos
    • Não nos afastamos completamente de um único grande banco SQL, mas estamos sofrendo uma classe específica de problemas que parece ligada a essa arquitetura
      Como somos uma grande empresa antiga, muitas vezes soluções técnicas criadas no passado por pessoas não técnicas acabam cristalizadas e precisam continuar sendo mantidas. Existe um processo de 5 etapas de transformação de dados SQL que começa no banco operacional e segue para diferentes gerações de modelos de dados conforme o tipo de negócio muda
      À medida que as camadas se acumulam, continuamos empilhando em cima das anteriores. Se uma aplicação criada há 10 anos sobre a camada de abstração 2 agora precisa de dados da camada 4, criamos scripts para devolver esses dados às camadas anteriores e seguimos em frente. No fim, isso virou uma massa enorme de tabelas e views interdependentes lendo dados de formas estranhas e nada intuitivas, e um projeto para arrumar isso foi considerado caro demais e adiado para a década de 2030
      Entendo quando as pessoas olham para esse problema e pensam em como isso poderia ter sido evitado. Mas, por algum motivo, parece impossível impor aos engenheiros de software um modo de trabalho que exija disciplina, então é preciso tornar impossível criar espaguete de qualquer forma. É aí que entra a separação. Se você não consegue ler os dados de outro serviço, não consegue criar esse espaguete que mata a velocidade dos dois lados
      A separação vertical da aplicação vira uma solução em software para um problema humano: a disciplina de engenharia fraca dentro da empresa
    • Hacker News não representa todo o ecossistema de tecnologia. Acho que a maioria das aplicações ainda usa um grande banco de dados SQL
      Recentemente publiquei um framework open source totalmente baseado em design orientado a dados, e recebi muitas respostas dizendo que esse design se encaixa perfeitamente. Colocar todos os dados em um só lugar realmente torna muitas coisas mais fáceis
      https://sql.ophir.dev
    • Nos lugares em que trabalhei, os motivos eram estes: migramos para microsserviços, um banco de dados gigantesco atrasava o desempenho, e operar e manter um DB grande era muito difícil
      Em um DB gigantesco havia muito entulho que ninguém usava, ninguém sabia por que existia, mas ainda não tinha certeza se era necessário; além disso, leituras e escritas exigiam estratégias de otimização diferentes
      Além disso, para que os times se movessem rápido, eles precisavam ter propriedade sobre o banco de dados e os armazenamentos de dados, sem esperar um DBA responder a um ticket
    • Acho que a causa é a mesma do surgimento de microsserviços e DevOps. A política fica mais fácil
      Quando trabalhei em uma grande empresa antiga, a maioria dos problemas era política e administrativa. Um único grande banco de dados SQL é eficiente, mas no momento em que a organização dona dele discorda da nova estratégia do CTO ou de outra unidade central do negócio, isso vira um problema
      Se somar a isso uma falha que mostre a baixa resiliência desse modelo, ele rapidamente se transforma em uma dor de cabeça política, e soluções técnicas, por mais óbvias que ainda pareçam para todos, ficam difíceis de levar adiante
  • Todo esse conselho é dependente de contexto
    Jogos só têm muitas operações que exigem uma abordagem orientada a colunas; nem todo domínio é assim. Empurrar cegamente boas práticas do mundo dos jogos para outros domínios só dificulta a vida de todo mundo e piora a maioria dos sistemas

    • Não é um problema exclusivo da abordagem por colunas. Se você colocar os dados em forma de array of structs, surgem oportunidades para empacotar os dados com mais eficiência e reduzir bastante o uso de memória da aplicação
      Campos booleanos de structs podem virar bitsets, campos anuláveis podem virar mapas esparsos ou densos, e campos de ponteiro ou referência podem virar arrays de inteiros menores indexando pools
      Em ambientes onde a CPU para com frequência por causa de acessos à memória, é impossível subestimar o impacto dessas mudanças. A diferença entre a latência do cache L3 e da RAM pode ser de cerca de 10x
    • O conselho de manter os dados acessados com frequência contíguos na memória se aplica a quase tudo em hardware moderno
      Em qualquer programa em que desempenho seja minimamente um problema, esse provavelmente é um dos caminhos para garantir bom desempenho
    • Também não era nada óbvio, quando ECS apareceu pela primeira vez, que jogos tinham tantas operações que exigiam uma abordagem por colunas. Levou muito tempo para convencer as pessoas a saírem do estilo orientado a objetos
    • Cada vez mais, isso parece a única forma de escrever código de alto desempenho
      A única coisa que se espera que continue escalando no hardware moderno é a densidade lógica. SRAM e tamanho de cache já não escalam bem nas litografias mais recentes, e a largura de banda da RAM também não aumenta muito há bastante tempo. Acho até que a largura de banda por núcleo pode ter diminuído. O acesso à memória já é um gargalo há algum tempo
    • Mesmo em muitas áreas de código de jogos em geral, a abordagem por colunas nem sempre é a correta; isso só vale para partes que precisam processar pelo menos milhares de “objetos”. Por exemplo, sistemas de partículas ou sistemas de navegação e colisão
      O design orientado a dados faz muito sentido dentro de subsistemas específicos, mas no código de gameplay de alto nível, salvo alguns gêneros, não necessariamente faz tanto sentido
  • Acho que a apresentação Data-Oriented Design and C++ do Mike Acton na CppCon 2014 é a melhor apresentação sobre programação já feita até hoje. Vale muito a pena assistir: https://youtu.be/rX0ItVEVjHc

    • É realmente excelente e também é a minha apresentação favorita. Pessoalmente, vejo Mike Acton como uma figura central na popularização de design orientado a dados e da arquitetura ECS
      Antes ele também liderou o Unity DOTS, mas infelizmente a Unity agora parece estar passando por instabilidade. O trabalho em si no DOTS, mesmo inacabado, é sólido
    • Se você quer ter uma noção de como desempenho de nível mundial é implementado, basta ver esse vídeo
      Passei a maior parte da minha carreira escrevendo aplicações web, mas foi vendo essa apresentação que entendi “por que alguém usa C?”
  • Andrew Kelley fez uma apresentação útil e divertida explicando como o design orientado a dados influenciou o trabalho dele no compilador Zig: https://vimeo.com/649009599

  • Até iniciantes podem aprender a programar de forma orientada a dados desde o começo
    Há livros que ensinam esse estilo para iniciantes, como How to Design Programs e A Data-Centric Introduction to Computing
    https://htdp.org/
    https://dcic-world.org/

    • Esses livros não são sobre isso aqui
  • Encontrei uma resenha online do livro: https://gist.github.com/seece/25ed1b2108cf5782718b026382f2c5...

    • A frase a seguir me pareceu interessante e contrária ao conselho geral
      “O grande culpado por atormentar e atrasar muitos projetos foi a insistência de que não se deve otimizar prematuramente. A razão de a otimização em estágio tardio ser tão difícil é que muito software acaba sendo construído de uma maneira que espalha instâncias de objetos por toda parte, mesmo quando elas não são necessárias.”
      Certamente existem aplicações em que desempenho é a prioridade máxima, e outras em que não é. Isso me fez pensar se, em apps onde desempenho importa, otimização prematura também pode ser aceitável. Fico me perguntando se essa leitura está correta
      Também existe algo chamado Data-Oriented Programming: https://www.manning.com/books/data-oriented-programming
      Fico me perguntando se os dois conceitos são a mesma coisa
  • O design orientado a dados é amigável para iniciantes. Isso porque ele lida apenas com a pureza da modelagem de dados, em vez de lidar com pessoas e negócios
    Quando eu era mais novo, a primeira etapa de um novo projeto era desenhar o modelo de entidade-relacionamento, e isso virava a base de tudo
    Hoje em dia, antes de começar pelo modelo de dados, primeiro procuro entender o problema e o domínio, e penso nas capacidades, em como agrupá-las e onde traçar seus limites

    • Com experiência, você percebe que o amor por dados e programação frequentemente acaba sendo deixado de lado por causa dos requisitos de negócio
      Ainda assim, este texto parece querer dizer que, se você focar em reunir os requisitos de dados desde o início, talvez a própria discussão sobre requisitos de negócio passe a ser menos necessária
  • Ao usar DoD, um dos conceitos centrais é não esconder os dados atrás de abstrações. A ideia é quanto menos, melhor
    Mas, lendo rapidamente o texto de introdução, tive justamente a impressão contrária. Ele fala demais e acaba abstraindo os conceitos centrais. Fui o único a achar irônico, como se não estivesse bebendo o próprio vinho?

  • O parágrafo de abertura é bem excelente. A escrita flui muito bem e as ideias são interessantes, então dá vontade de continuar lendo
    “Dados são tudo o que temos. Dados são aquilo que transformamos para criar a experiência do usuário. Quando abrimos um documento, o que carregamos é dado. Os gráficos na tela, os pulsos dos botões no gamepad, a causa de os alto-falantes criarem ondas no ar, a forma como você sobe de nível, e o modo como os inimigos descobrem sua posição e atiram em você também são dados. O tempo que a dinamite leva para explodir e o número de anéis perdidos ao cair nos espinhos também são dados. A posição e a velocidade atuais de cada partícula na bela cena depois de terminar o jogo, lidas do disco e trazidas para a sua vida, são o resultado de transformações em uma máquina movida pelo código-fonte que você deu ao compilador, pelas instruções emitidas pelo assembler e pelas instruções decodificadas.”

    • Vejo muito esse tipo de ideia na literatura sobre design orientado a dados, mas sempre me parece desnecessariamente reducionista
      Como um “banho de água fria” para montar o cenário e fazer a pessoa sair da forma de pensar baseada em abstrações orientadas a objetos, isso pode até ser útil. Mas, fora isso, me parece tão útil quanto um engenheiro dizer “olhe ao seu redor! Tudo é feito de átomos! Engenharia é, no fundo, mover átomos!”
      Não está errado, mas também não ajuda muito na hora de fazer engenharia de verdade