Usando Bit Flags e EnumSets em Java.
Os sinalizadores de bits, comumente referidos como campos Bit, são uma forma eficiente de armazenar vários valores booleanos relacionados em um único tipo primitivo. Internamente representado em binário, você pode decidir quanto grande o tipo de armazenamento precisa ser - por exemplo, um inteiro de Java fornecerá espaço para 31 bandeiras. Sendo um tipo de 32 bits, você assumiria ter acesso a essas bandeiras, no entanto, devido ao fato de ser um valor assinado, o bit mais significativo é reservado para armazenar seu sinal +/-.
As bandeiras normalmente são armazenadas como constantes públicas dentro da classe relacionada, por exemplo, a classe Padrão inclui os sinalizadores 'CASE_INSENSITIVE' e 'MULTILINE' para alterar os critérios de correspondência. Definir os valores como potências incrementais de 2 permite ao usuário compor várias constantes juntas usando o | (OR) para obter a combinação de bandeira desejada. O implementador é então capaz de basear a execução dos métodos nos sinalizadores passados, verificando a presença do valor constante usando o & amp; (AND) como uma máscara de bits. Essa idéia pode ser descrita de forma mais significativa usando o exemplo abaixo.
Como você pode ver, eu definei 5 constantes diferentes com valores específicos que correspondem a diferentes representações binárias. Em relação à constante final que eu configurei para o decimal 15, em essência, isso enche todas as combinações de valores criadas anteriormente. Dentro do bloco de método, verifico a presença de cada sinalizador, mascando o parâmetro 'flags' com o valor constante. Se o valor resultante for igual à constante especificada, podemos atuar nesta condição.
Acima estão alguns exemplos do método que está sendo usado de múltiplas maneiras. O terceiro exemplo mostra a capacidade de compor valores de várias bandeiras (representação binária 1100).
O uso tradicional de bit flags ocorreu por muitos anos e é um mecanismo de armazenamento muito performant (especialmente na renderização gráfica). No entanto, pode ser muito fácil para o código resultante ser difícil de entender. Outra questão flagrante é que eles não são de tipo seguro, anulando os benefícios de ter um sistema de tipo implementado. No entanto, EnumSets tem a eficiência de bit flags, mas sem a perda de segurança, o sistema de tipo fornece. Devo salientar que existe outra implementação do Set chamada BitSet, que fornece funcionalidades semelhantes. Recomenda-se que, se você deseja um sistema de sinalização, como o caso de uso descrito, um EnumSet fornecerá os melhores resultados.
No caso de um EnumSet, você deve primeiro definir seu tipo enumerado, que encapsula todas as constantes desejadas. Sempre que eu defini a constante 'ALL_OPTS' no primeiro exemplo, criei um EnumSet consistindo de todas as constantes no tipo de bandeira. EnumSet implementa a interface Set, para que você possa usá-lo como faria com um conjunto típico, chamando 'contains' no mesmo para consultar a presença de um determinado sinalizador.
Acima estão alguns exemplos de utilização do EnumSet no lugar de um típico sistema de sinalização de bits. Como você pode ver, podemos completar todos os exemplos que foram possíveis no caso de uso anterior, mas desta vez é mais legível e somos menos propensos a erros.
toco.
Apenas outro blog do WordPress.
Pós-navegação.
Um Quick Bitmask HOWTO para programadores.
Atenção: o material Highly Geeky segue.
Atualmente, estou trabalhando em um grande banco de dados para um cliente. Atualmente, eu realmente estou fazendo uma nova versão do banco de dados em uma máquina de gritar normalizada. Eu encontrei um problema recentemente em que alguns dos valores são armazenados como bitmasks. Eu sabia o que era uma máscara de bits, mas geralmente os considerava como magia vudu deixada para hackers loucos de C. Até agora. Eu entrei em contato com meu mentor do hacker louco do Voodoo, Jeremy Brand, e perguntei como eles trabalhavam.
Aqui é um rápido tutorial:
em vez de contar 0, 1, 2, 3, 4, 5 e # 8230; você poderia com poderes de 2.
Quando você faz uma coisa com um desses poderes de dois, você pode.
adicione-os a outros poderes de 2 e, em seguida, divida o que.
você começou com novamente.
A soma de seus identificadores é 7 (vamos chamar este $ soma).
Então, mais tarde você pode verificar 7 para ver o que está em sua cesta:
$ sum mod 4 igual a 0? (então não há maçã no carrinho)
o $ sum mod 2 equivale a 0? (então não há laranja no carrinho)
o $ sum mod 1 email 0? (então não há banana no carrinho)
Usar bitmasmas não é mais fácil de usar, mas é rápido.
É rápido porque os computadores já são em bits. Este exemplo.
está usando memória de 3 bits. Normalmente, você terá 16 opções (como eu.
tem 3 aqui) por causa do tamanho de um número inteiro. Se você é sortudo.
você estará usando C ou mesmo o mysql que pode acessar todos os 32 bits de um.
inteiro, você terá 32 opções.
A razão pela qual os computadores usam base-2 para começar são porque.
Com o hardware de armazenamento, há realmente apenas dois estados: ligado e desligado.
As unidades mais simples que você pode armazenar e desligar mais.
armazenamento que o dispositivo pode ter.
FYI, você pode usar o google para sua calculadora:
Finalmente, isso faz sentido. Ainda estou completamente perdido na matemática real que faz isso funcionar (o que me irrita), mas consegui obter um programa de prova de conceito funcionando, o que pode ajudar outros programadores deficientes em bitmask lá fora:
O truque é o & amp ;. Se o resultado for 0 (zero), o valor da máscara de bits única não está presente na soma da máscara de bits. Tenho certeza de que isso tem algo com o fato de que você não pode adicionar nenhuma lista separada de valores de máscara de bits e obter a mesma soma duas vezes (ou seja, 1 + 2 + 4 = 7, 2 + 4 + 8 = 14). Mais uma vez, eu só sei # 8220; funciona [tm] & # 8221 ;. Espero que isso ajude alguém a lá.
Eu principalmente escondiendo isso aqui, então a próxima vez que minha mente retardada pode se enrolar em torno de máscaras de bits, eu posso verificar novamente em meu próprio site. Se você tiver dúvidas sobre este não envie um e-mail para mim, porque eu ainda acho que pequenos homens verdes fazem esse truque matemático & # 8220; # 8221; trabalhos. Porra, eu gostaria de obter um diploma de Ciência da Computação em vez de uma Informação de Computador. Sys. grau.
16 pensamentos sobre & ldquo; Um Quick Bitmask HOWTO para Programmers & rdquo;
Finalmente! Eu vi isso muitas vezes, mas não consegui descobrir o nome, obrigado.
Você ajudou pelo menos um codificador deficiente em bitmask 🙂
Eu não posso acreditar nos tipos de pessoas que se chamam programadores nos dias de hoje. E os gerentes não conhecem; para eles, qualquer um que possa jogar algumas palavras-chave arrumadas deve saber o que eles estão fazendo. E, portanto, a quantidade irresistível de sistemas de software de amaldiçoamento, de qualidade inferior, com documentação fraca e design ainda pior. Você senhor, é um idiota, e eu odeio seu tipo.
Você não tem IDEA que tipo de programador eu sou. Antes de tirar a boca, você provavelmente deveria tomar o tempo para me conhecer. Só porque eu não sabia o que era uma máscara de bits (ou como usá-la efetivamente) não significa que eu não sou bom com SQL, OOP, etc. Pelo menos eu entendi isso para mim mesmo Saiba como usá-los e pode reconhecer o fato de que eles são uma solução mais elegante para muitos problemas.
Que tal você derrubar alguém para tentar aprender a ser um programador melhor? Você, senhor, é um idiota, e eu odeio você.
Eu acho que a idéia de bitmasks é algo que nem todos devem saber. Você pode desenvolver aplicativos por anos e nunca tropeçar com a necessidade deles, especialmente quando não usa DBs.
As máscaras de bits são úteis, mas onde eu começo a ficar nervoso são as mudanças de bits, p. em Java. Eles são ainda mais estranhos (e acho que o código tende a ficar muito ilegível).
Aren't Integer comparações sempre transformadas em bitmasks por um compilador decente?
Então, ao invés de dissing alguém, como eu só me ajudarei 😉 A matemática que você está procurando atrás de tudo isso é extremamente simples. O problema é que, para alguns, eles não falam binário. Suponhamos que nós temos quatro bits. Não bytes, bits. Então, alinhe, e eles se parecem com isto:
Olhando para esse padrão, você notará que o 1 está movendo um espaço para a esquerda (daí a mudança de bit) para cada novo valor.
Ok, agora vamos falar sobre & # 8220; e # 8221; Bitwise & # 8220; e & # 8221 ;. O que isso significa? Bem, se você comparar dois * binários * números como:
0010 = 4 decimais.
0011 = 5 decimais.
Veja o número mais à direita de cada conjunto de bits. O topo é 0 e o inferior é 1. Existem apenas duas regras para lembrar:
Lembre-se desta matemática binária (base 2), não matemática decimal (base-10), e não usamos & # 8220; bitwise e (& # 038;) & # 8221; em matemática decimal, apenas operadores gostam de (+, -, /, x,% entre outros).
Então, & # 8220; e & # 8221; Cada coluna de bits e você obtém o resultado:
0011 = 5 decimais.
0010 = 4 decimais.
0010 = 4 decimais = Resultado.
Que bem isso faz? Bem, assim como sua cafeteira, você acabou de criar um filtro. Imagine se isso parece ser assim:
0011 = 5 decimais = A user & # 8217; s & # 8220; direitos de acesso & # 8221 ;.
0010 = 4 decimal = A permissão necessária para acessar esta página.
Pergunta de US $ 60 000: se o usuário chegar nesta página, eles vêem a página?
Mas sim!! O segundo bit está definido em seus & # 8220; direitos de acesso & # 8221 ;.
Espero que ajude.
Btw. Trabalhei há muito tempo em software, incluindo alguns projetos renomados mundiais (NFS: Underground, por exemplo). Aprendi, se alguém tiver atitude, ele acompanha a insegurança. O melhor e o mais brilhante é fácil, acessível e sempre pronto para aprender. Ninguém sabe tudo sobre tudo.
Ainda assim, tenho duas sugestões:
a) Você deve bitwise OR (|) os valores para compor a máscara de bits, em vez de adicionar (apenas por motivos históricos;));
b) Para testar, você deve bit a bit AND a máscara de bits com um valor e, em seguida, comparar com o mesmo valor testado (em vez de 0);
Suponha que você tenha a seguinte bitmask:
1010 & # 8211;> bitmask (10 em decimal)
E você quer testar para:
0110 & # 8211;> valor (6 em decimal)
Se você tiver bit a bit AND (& # 038;) os dois, você obterá:
0010 & # 8211;> bitmask & # 038; valor (2 em decimal)
O que é maior do que zero, provocando TRUE. No entanto, o valor do teste não está dentro da máscara de bits.
Então, seu script funciona se os valores que estão sendo testados são potências de 2, mas falham de outra forma.
Você poderia facilmente torná-lo à prova de prova ao testar o mesmo valor, assim:
função testbitmask ($ value, $ bitmask)
se (($ value & # 038; $ bitmask) == $ value) retornar TRUE;
Esta função funciona se a sua bitmascara é composta por poderes de 2 ou qualquer outra combinação de números.
Note-se que existe uma razão para que bitmasks sejam feitas de poderes de dois. No exemplo dado, a máscara de bits 1010 deve representar os valores 2 (0010) e 8 (1000), OR.
Se você adicionar 10 (que é 1010 em binário) para a máscara de bits, você obteria # 8230; 1010! Como, então, você poderia saber se a máscara de bits contém 2, 8 ou 10? Bem, você não conseguiu.
Para evitar esse problema, você só deveria usar os poderes de dois na sua máscara de bits, pois esses números deslocam um bit para o lado esquerdo, assim:
Mas, como em algumas situações, é útil usar outros números (você pode, se você tiver cuidado), seus scripts melhor estarão prontos ... 🙂
Espero que isto ajude!
Quanto a & # 8220; Mr. & # 8221; O comentário de John, acho que ele deve ter nascido ensinado ou algo assim # 8230; 😛
então eu ainda tenho dúvidas sobre este & # 8230;
91 | 92 = 95 (1011011 | 1011100 = 1011111)
95 & # 038; 91 = 91 CORRETA.
95 & # 038; 92 = 92.
Eu reconheço que os poderes de 2 devem ser usados para evitar apenas essa complicação. No entanto, eu tenho um gerenciador de desenvolvimento que está convencido de que pode ser feito com qualquer conjunto de números. Alguém poderia iluminar para mim como eu posso usar não poderes de 2 em uma máscara de bits e ainda ser capaz de evitar falsos positivos?
então eu ainda tenho dúvidas sobre este & # 8230;
91 | 92 = 95 (1011011 | 1011100 = 1011111)
95 & # 038; 91 = 91 CORRETA.
95 & # 038; 92 = 92.
Eu reconheço que os poderes de 2 devem ser usados para evitar apenas essa complicação. No entanto, eu tenho um gerenciador de desenvolvimento que está convencido de que pode ser feito com qualquer conjunto de números. Alguém poderia iluminar para mim como eu posso usar não poderes de 2 em uma máscara de bits e ainda ser capaz de evitar falsos positivos?
Você precisa usar bitmasks.
Se você quiser mais opções, use um campo de máscara de bits maior (por exemplo, 0000000 em vez de apenas 0000).
Uma coisa que vou adicionar, o principal problema com estes (e eu não gosto muito) é que você pode ficar sem bit / flags que você pode atribuir rapidamente.
Por exemplo, um número de 32 bits significa que você só pode ter até 32 bandeiras de permissão diferentes, ou itens em seu carrinho etc.
Você não usaria uma máscara de bits para lidar com os itens que um usuário tem em seu carrinho de compras, pois haveria 1000 itens (e para ter 1000s de itens suportados, você precisaria de uma máscara de bits de 1000 bits + para lidar com cada item).
Obrigado. Muito bom tutorial e ótimas respostas! Com exceção do único cara que deve morrer e limpar o pool de genes um pouco & # 8230 ;.
Esse joão deve ser totalmente retardado.
Quão estúpida pode ser uma pessoa?
Obrigado! Fui encarregado de trabalhar com um db que usa máscaras de bits e quase desenhou um espaço em branco. Eu esqueci completamente como tudo se juntou. Este artigo lembrou totalmente o padrão de pensamento de bits para mim!
Eu acho que John tem um ponto, embora ele seja um idiota. Um verdadeiro programador entende os conceitos subjacentes, isso deve ser aprendido quando você inicia a programação pela primeira vez. Ligar a si próprio (no sentido literal, não o autor) um profissional quando você não conhece os princípios básicos é como se chamar de mecânico e não saber que os carros usam motores de combustão, mas que consertam os motores de forma feliz, porque eles usam peças. Eu não gostaria que o mecânico funcionasse no meu carro. Note-se que, na minha analogia artificial, o mecânico não precisa conhecer a termodinâmica, simplesmente como funciona de modo geral, assim como um programador não precisa usar o microcódigo ou o montador.
Eu sou uma estudante junior e nunca mais ouvi falar de bitmask até hoje. Ocorreu no meu trabalho @ IT quando eu perguntei a um dos nossos & # 8220; gênios & # 8221; para um tutorial sobre algo. Assim como foi mencionado em uma publicação anterior, o melhor no campo é o mais útil e humilde. Aprendi que as pessoas inseguras que andavam por aí dizendo aos analfabetos que são hackers e programadores têm a atitude de John e acabam por falhar por causa disso. O trabalho em equipe é o melhor ambiente de aprendizagem na minha opinião. É impossível saber tudo.
Olá, eu coloquei-se sobre isso procurando uma atualização (eu vi isso uma vez antes em uma aula e esta seria minha primeira aplicação).
Posso estar confuso, mas acho que pode haver um problema com seu algoritmo de leigos:
Nosso carrinho pode ter os seguintes itens nele (com os valores fornecidos em seu exemplo.)
Vamos assumir que apenas uma laranja e uma maçã estão no carrinho.
sum mod 4 0 (uma maçã está no carrinho)
sum mod 2 = 0 (uma laranja NÃO está no carrinho) - & gt; ERRO.
Mas e se nós tivéssemos uma maçã no carrinho.
Isso não está funcionando porque estamos lidando com números inteiros no exemplo? (Tive a impressão de que o compilador e a velocidade de troca de bits dentro de um processador cuidariam a conversão).
Se uma máscara de bits pode ser aplicada com números inteiros, eu suspeito que eu preciso aplicar mais do que um mod para obter o resultado. Você pode me dizer o que eu faltava?
PS: Desculpe por escrever isso cerca de 3 anos de atraso; & gt;)
Swift 3.0.
Quase idêntico ao Swift 2.0. OptionSetType foi renomeado para OptionSet e enums são escritas minúsculas por convenção.
Em vez de fornecer uma opção nenhuma, a recomendação Swift 3 é simplesmente usar um literal de matriz vazia:
No Swift 2.0, as extensões de protocolo cuidam da maior parte do gabarito para estas, que agora são importadas como uma estrutura que está em conformidade com OptionSetType. (RawOptionSetType desapareceu a partir do Swift 2 beta 2.) A declaração é muito mais simples:
Agora podemos usar semânticas baseadas em conjunto com MyOptions:
Olhando para as opções Objective-C que foram importadas pela Swift (UIViewAutarização, por exemplo), podemos ver que as opções são declaradas como uma estrutura que está em conformidade com o protocolo RawOptionSetType, que, por sua vez, está em conformidade com _RawOptionSetType, Equatable, RawRepresentable, BitwiseOperationsType e NilLiteralConvertible . Podemos criar o nosso próprio como este:
Agora, podemos tratar este novo conjunto de opções, MyOptions, tal como descrito na documentação da Apple: você pode usar uma sintaxe semelhante ao enum:
E também se comporta como se esperássemos opções para comportar-se:
Últimas: Modificações para Swift 1.1 beta 3.
Xcode 6.1 Beta 2 trouxe algumas alterações ao protocolo RawOptionSetType (veja esta entrada de blog Airspeedvelocity e as notas da versão da Apple).
Com base no exemplo Nate Cooks, aqui está uma solução atualizada. Você pode definir sua própria opção como esta:
Pode então ser usado dessa forma para definir variáveis:
E assim teste para bits:
Exemplo Swift 2.0 da documentação:
Você pode encontrá-lo aqui.
Em Swift 2 (atualmente beta como parte do beta Xcode 7), NS_OPTIONS, os tipos de estilo são importados como subtipos do novo tipo OptionSetType. E graças ao novo recurso Extensões de protocolo e à forma como o OptionSetType é implementado na biblioteca padrão, você pode declarar seus próprios tipos que estendem o OptionsSetType e obter todas as mesmas funções e métodos que importaram NS_OPTIONS.
Mas essas funções não são mais baseadas em operadores aritméticos bit-bit. Que trabalhar com um conjunto de opções boleanas não exclusivas em C requer máscaras e bits em um campo é um detalhe de implementação. Na verdade, um conjunto de opções é um conjunto. uma coleção de itens exclusivos. Então, OptionsSetType obtém todos os métodos do protocolo SetAlgebraType, como a criação da sintaxe literal da matriz, consultas como contém, mascaramento com interseção, etc. (Não há mais que lembrar qual personagem engraçado usar para qual teste de associação!)
Se você não precisa interoperar com Objective-C e quiser apenas a semântica de superfície de máscaras de bits em Swift, escrevi uma "biblioteca" simples chamada BitwiseOptions que pode fazer isso com enumerações Swift regulares, por exemplo:
e assim por diante. Nenhum pedaço real está sendo lançado aqui. Estas são operações definidas em valores opacos. Você pode encontrar a essência aqui.
Se a única funcionalidade que estamos precisando é uma maneira de combinar opções com | e verifique se as opções combinadas contêm uma opção específica com & amp; uma alternativa à resposta de Nate Cook poderia ser esta:
Crie um protocolo de opções e sobrecarregue | e & amp; :
Agora podemos criar opções estruturadas de forma mais simples assim:
Eles podem ser usados da seguinte forma:
Como Rickster já mencionou, você pode usar OptionSetType no Swift 2.0. Os tipos NS_OPTIONS são importados como compatíveis com o protocolo OptionSetType, que apresenta uma interface definida para opções:
Isso lhe dá essa maneira de trabalhar:
Apenas publicando um exemplo extra para qualquer outra pessoa que se perguntou se você poderia combinar opções compostas. Você pode, e eles combinam como você esperaria se você estivesse acostumado com bons e antigos campos de bits:
Ele aplana o conjunto [.AB,.X] para [.A,.B,.X] (pelo menos semanticamente):
Ninguém mais mencionou isso - e eu meio que maltratou depois de algum brincadeira - mas um Swift Set parece funcionar bastante bem.
Se pensarmos (talvez para um diagrama de Venn?) Sobre o que um pouco de máscara representa realmente, é um conjunto possivelmente vazio.
Claro, ao abordar o problema dos primeiros princípios, perdemos a conveniência de operadores bit a bit, mas ganhamos poderosos métodos baseados em conjuntos que melhoram a legibilidade.
Aqui está o meu brincadeira, por exemplo:
Eu acho isso agradável porque sinto que ele vem de uma abordagem de princípios básicos para o problema - bem como Swift - ao invés de tentar adaptar as soluções de estilo C.
Também gostaria de ouvir alguns casos de uso de Obj-C que desafiariam esse paradigma diferente, onde os valores brutos inteiros ainda mostram mérito.
A fim de evitar a codificação dura das posições dos bits, o que é inevitável quando se usa (1 & lt; 0), (1 & lt; 1), (1 & lt; & lt; 15) etc. ou pior ainda 1, 2, 16384 etc. ou alguma variação hexadecimal, primeiro se poderia definir os bits em um enum, então deixe o enum fazer o cálculo bit ordinal:
Re: Criações de sandbox e bookmark usando conjuntos de opções com várias opções.
solução para a necessidade de combinar opções para criações, útil quando nem todas as opções são mutuamente exclusivas.
A resposta de Nate é boa, mas eu faria DIY, assim:
Use um Tipo de Conjunto de Opções, no swift 3 use OptionSet.
Eu uso o seguinte Eu preciso dos dois valores que posso obter, rawValue para arrays de indexação e valor para sinalizadores.
E se alguém precisar de mais, apenas adicione uma propriedade calculada.
Usando bitmasks para armazenar configurações.
Muitas vezes, precisamos armazenar vários booleanos para determinar as configurações de um usuário. Bitmasks são uma boa maneira econômica de fazê-lo. A idéia é usar um único número inteiro onde cada bit representa um desses booleanos. Isso é melhor do que salvar cada configuração individual em uma coluna de banco de dados diferente.
Escolha posições de bits para cada configuração. Digamos que queremos armazenar as configurações de notificação.
Agora vamos desativar todas as configurações:
Agora vamos ativar notificações de comentários:
Vamos ver como isso parece em binário:
O bit na posição 1 (COMENTÁRIOS) foi definido como 1 enquanto o resto não mudou.
A operação 1 & lt; & lt; N coloca (desloca) o valor 1 para a posição N de modo que, por exemplo:
Agora | e & amp; são as operadoras OR e AND usuais, mas aplicadas em um nível de bit para que:
Vemos que a | = 1 & lt; & lt; N liga o bit N-posicionado no inteiro a.
inverte todos os bits em uma variável para que:
O que é todos os bits definidos para 1, exceto o bit 1 e o bit 3, se falamos de números inteiros assinados.
Para desligar um pouco, simplesmente faça.
(1 & lt; & lt; COMMENTS) terá todos os bits ON exceto o que está na posição COMENTÁRIOS.
Para verificar se as configurações específicas estão ON, basta verificar.
Escrito por Emmanuel Turlay.
15 Respostas.
Isso é ótimo. Uma queda potencial é que você perde a capacidade de consultar e informar sobre essas configurações. "Mostre-me os usuários com seguidores desativados" torna-se um pouco (ha) mais difícil.
Esse é um ponto justo.
& # x000A; Se eu não estou enganado, todos os sabores do SQL suportam operações bit a bit não? Assim, pode-se consultar com SELECT * FROM usuários WHERE configurações & amp; (1 & lt; 3) & gt; 0.
@ neutralino1, essa é realmente a solução para isso. Eu adoro bitmasks também, eles certamente tornam algumas tarefas muito mais fáceis (e economizam muitas colunas extras em seu banco de dados).
MAS, você sempre tem que ter cuidado ao usá-los, e não apenas jogar tudo lá: P.
Na verdade, o uso de bitmasks requer alguns testes sérios.
& # x000A; e você não pode usá-lo para tudo. No meu caso, eu uso isso para uma coleção estúpida de caixas de seleção.
Esta teria sido a única maneira de coisas armazenadas do dev de volta, quando a memória era um problema. Não seria bom ver o quão rápido o código moderno poderia ser se o tempo fosse gasto para acelerá-lo.
& # x000A; eu realmente aprendi essa técnica enquanto codificava o experimento ATLAS no CERN, que contém milhares de chips eletrônicos, onde o espaço físico e o espaço lógico são recursos limitados.
@ neutralino1 Sim, é definitivamente uma técnica subutilizada. Eu usei uma técnica semelhante em um micro-controlador para um alarme anti-roubo. Com 8 zonas, precisamos de apenas 3 bytes para controlar se estão ativados, alarmados e disparados. Então é apenas uma questão de configurar alarmes / interruptores e LEDs para disparar esses pontos.
& # x000A; as operações Bitwise não são mais ensinadas no fluxo principal.
@mikeymike, acho que você vai apreciar este.
bitmaps em ruby? Voce deve estar brincando.
& # x000A; Se você estiver usando bitmaps na memória, é necessário alocar mais memória para objetos para trabalhar com eles do que economizar espaço. & # x000A; Se você estiver usando bitmaps no banco de dados, você não pode trabalhar com esses dados de forma sensata (sem índices, sem consultas limpas), para que você use bitfield apenas como formato de armazenamento aleijado. Além disso, cada banco de dados possui estruturas próprias, performantes e indexáveis para armazenar esses dados. & # x000A; & # x000A; & # x000A;
Não mencionando que nunca esqueciaria a legibilidade do sistema e do código para economizar poucos bytes de espaço por registro. Parece uma otimização prematura, hein?
No Ruby você não obtém nenhuma performance, legibilidade de código, menor espaço de armazenamento / memória, normalização de dados, boa interface de consulta. Não há, literalmente, nenhuma vantagem.
@sheerun eu tenho uma tabela dedicada às configurações dos usuários com dezenas de colunas booleanas e tantas linhas como usuários. Isso me assusta. Eu prefiro muito um único campo inteiro na tabela de usuários.
& # x000A; eu nunca preciso fazer uma consulta sobre eles, eu só preciso verificar as configurações de um determinado registro.
Agora, para ser claro, nunca disse que as pessoas deveriam usar essa técnica cegamente. Todos devem ser sensíveis a como ele se encaixa nesses requisitos. Assim como tudo o resto.
& # x000A; Além disso, usei ruby aqui para ilustrar o ponto, mas a publicação foi principalmente destinada a mostrar a técnica ao invés da linguagem usada para aplicá-la.
Uma vez, trabalhei na empresa, que estava licenciando um produto conectado a um banco de dados proprietário de terceiros, que quase não controlávamos. Havia uma tabela em particular que precisava de duas colunas de tipos inteiros adicionais. Com apenas uma coluna de "reposição" na tabela, sugeri que usássemos um valor ponderado para resolver o problema.
Não é uma idéia antiga, mas uma para lembrar "just-in-case".
Devo também salientar que o código que lidava com esses valores era mais difícil de ler. O Bit Shifting é um conceito fácil de entender, mas a menos que você esteja trocando bit durante todo o dia, é obrigado a diminuir a velocidade de alguns desenvolvedores e torná-los a uma pausa maior do que eles precisam para resolver um problema na produção.
Alguns métodos de tipo wrapper de conveniência acrescentariam valor.
O endianness se torna um problema com esse tipo de abordagem?
Quando você tem 65 funções + (64 bits / 8 = 8 bytes), será de maneira errada. Como o MySQL possui somente 8bytes (tipo de dados BIGINT). Como corrigi-lo ?
No comments:
Post a Comment