Estou trabalhando na aprendizagem de Haskell, então tentei implementar uma função de média móvel. Aqui está o meu código: onde o usuário chama mática com um comprimento para cada média e a lista de valores (por exemplo, a média 4 1,2 ... 100). No entanto, quando eu executo o código na entrada de 4,4 mil milhões de mAverage. Eu entendo que leva 3,6 segundos em ghci (usando: set s) e usa um gigabyte de memória. Isso parece muito ineficiente para mim, pois a função equivalente leva uma fração de segundo no Python. Existe alguma maneira que eu poderia tornar meu código mais eficiente perguntou 27 de dezembro às 19:59 Uma maneira de fazer a janela deslizante é passar na primeira soma como um flutuador. Passar na lista original (para ser usado para subtrair a soma atual) e a lista original com k entradas caiu (para ser usado para adicionar a soma atual). Então, a próxima soma é a soma passada em menos o primeiro elemento da lista de subtração mais o primeiro elemento da lista de adição. Ndash Chai T. Rex 27 de dezembro 16 às 20:33 Se você quiser aprender algo novo, você pode dar uma olhada nesta solução agradável para o problema da Mudança de Média. Está escrito por um dos meus alunos, então eu não reivindico autoria. Eu realmente gosto porque é muito curto. O único problema aqui é a função média. Tais funções são conhecidas como ruins. Em vez disso, você pode usar belas dobras por Gabriel Gonzalez. E sim, esta função leva o tempo O (k) (onde k é tamanho da janela) para calcular a média da janela (acho melhor porque você pode enfrentar erros de ponto flutuante se você tentar adicionar apenas um novo elemento à janela e subtrair o último) . Oh, ele também usa a mônada do estado :) UPD: depois de uma revisão do código, notei que não é necessário usar dobras aqui para calcular a média. Você sabe que o comprimento sempre será n, então você pode simplesmente colocar a função média na cláusula where. Respondeu 27 de dezembro às 23:26 Heres uma solução para você. A idéia é escanear duas listas, uma onde começa a janela de média e outra onde ela termina. Conseguir um final da lista de uma lista custa tanto como escanear a parte falhando e não copiando nada. (Se o tamanho do Windows fosse geralmente bastante grande, poderíamos calcular o valor restante junto com a contagem da soma de inicialização. De uma vez.) Geramos uma lista de somas parciais conforme descrito no meu comentário e, em seguida, divida-as pela largura do Windows para obter as médias . Enquanto slidingAverage calcula médias para a posição tendenciosa (largura da janela para a direita), centeredSlidingAverage calcula as médias centradas, usando metade da largura da janela para a esquerda e para a direita. Quando eu tento o comprimento de slidingAverage 10 1..1000000. Demora menos de um segundo no meu MBP. Devido à preguiça. CentralizadoSlidingAverage leva aproximadamente o mesmo tempo. Respondido 27 de dezembro às 22:25 Sua resposta 2017 Stack Exchange, Inc. Tentamos algumas técnicas de cálculo correntes para alisar a alteração nos dados do ADC no AtMega48 para o controle de luzes (PWM) ao girar uma panela (ADC). Os filtros (pseudo-códigos): observei que os filtros são muito agradáveis. Mas devagar em resposta, o que é esperado. Procuro técnicas como a média móvel exponencial. Disse ser mais receptivo. Existe outro como este Como ele diz: onde está entre 0 e 1. Como codificar e otimizar esses códigos sábios (sem usar flutuadores) Ou Como eu converteria os flutuadores em números inteiros correspondentes para tornar o código pequeno, rápido e responsivo. E eu mantive 1 Outro, então, que não funcionará como esperado. Por Idve mudar todas as variáveis para flutuar. Por favor, não se concentre na seguinte declaração por enquanto, mas observe. Manter flutuadores na minha base de código está preenchendo a memória do programa de 45 a 137, no caso de Você pode implementar com sobrecarga mínima, limitando as frações binárias. Eu usei isso com bons resultados. Pegue o resultado existente, Deslize N lugares direito para dividir por 2N Subtrai-lo do resultado existente. Adicionar novos dados Isso não é tão rápido em mudar com uma mudança de etapa nos dados de entrada como você deseja, mas é fácil de implementar e efetivo o suficiente como um filtro em muitos casos. Você pode acelerar sua resposta ao tomar decisões informais quanto ao seu comportamento em casos que são muito diferentes. Por exemplo, mantenha uma contagem de entradas seqüenciais que são mais que um limite diferente do resultado existente. Se essa contagem ultrapassar algum limite, altere a proporção de divisão N por algum fator. Por exemplo, N é geralmente 4- os resultados são deslocados para direita 4 vezes 16. Se a entrada for mais que xxx longe da resposta, faça apenas duas mudanças para a direita e multiplique a nova amostra em 4 antes de adicionar. Respondeu 4 de outubro 12 às 6: 08Stack Overflow: a arquitetura - edição de 2016 Para ter uma idéia do que tudo isso faz, deixe-me começar com uma atualização no dia médio no Stack Overflow. Então você pode comparar com os números anteriores de novembro de 2013. heres um dia de estatísticas de 9 de fevereiro de 2016 com diferenças desde 12 de novembro de 2013: 209,420,973 (61,336,090) Solicitações HTTP para o nosso balanceador de carga 66.294.789 (30.199.477) daquelas foram cargas de página 1,240,266,346,053 (406,273,363,426) bytes (1,24 TB) de tráfego HTTP enviado 569,449,470,023 (282,874,825,991) bytes (569 GB) total recebido 3,084,303,599,266 (1,958,311,041,954) bytes (3,08 TB) total enviado 504,816,843 (170,244,740) Consultas SQL (apenas a partir de solicitações HTTP) 5,831,683,114 (5,418,818,063) Redis atinge 17.158.874 (não rastreado em 2013) Pesquisas elásticas 3,661,134 (57,716) O Tag Engine solicita 607,073,066 (48,848,481) ms (168 horas) gasto executando consultas SQL 10,396,073 (-88,950,843) ms (2,8 horas) gasto em Redis atinge 147,018,571 (14,634,512) ms (40,8 horas) gasto na solicitação do Tag Engine 1,609,944,301 (-1,118,232,744) ms (447 horas) gasto na média ASP. Net 22.71 (-5.29) ms (19.12 ms na ASP. Net) para uma missão de 49.180.275 A página de íons renderiza a média de 11,80 (-53,2) ms (8,81 ms em ASP. Net) para 6,370,076 renderizações de página inicial. Você pode estar se perguntando sobre a drástica redução de ASP. Net no tempo de processamento em relação a 2013 (que foi de 757 horas) apesar de 61 milhões mais Solicita um dia. Isso deve-se a uma atualização de hardware no início de 2015, bem como a um alto desempenho ajustado dentro das próprias aplicações. Por favor, não esqueça: o desempenho ainda é um recurso. Se você está curioso sobre mais especificações de hardware do que estou prestes a não apresentar. A próxima publicação será um apêndice com especificações de hardware detalhadas para todos os servidores que executam os sites (atualize-o com um link quando estiver ao vivo). Então, o que mudou nos últimos 2 anos Além de substituir alguns servidores e equipamentos de rede, não muito. Heres uma lista de alto nível de hardware que executa os sites hoje (observando o que é diferente desde 2013): 4 Servidores Microsoft SQL (novo hardware para 2 deles) 11 Servidores Web IIS (novo hardware) 2 Servidores Redis (hardware novo) 3 Tag Servidores de mecanismo (novo hardware para 2 dos 3) 3 servidores Elasticsearch (mesmo) 4 balanceadores de carga HAProxy (adicionados 2 para suportar o CloudFlare) 2 redes (cada um dos extensores de tecido Nexus 5596 Core 2232TM atualizado para 10Gbps em todo o lado) 2 firewalls Fortinet 800C ( Substituiu as ASAs Cisco 5525-X) 2 roteadores Cisco ASR-1001 (roteadores Cisco 3945 substituídos) 2 roteadores Cisco ASR-1001-x (novos) O que precisamos para executar o estouro de pilha Isso não mudou muito desde 2013. mas devido às otimizações E o novo hardware mencionado acima, dependeram da necessidade de apenas um servidor web. Nós testámos, sem querer, isso, com sucesso, algumas vezes. Para ser claro: estou dizendo que funciona. Não estou dizendo que seja uma boa idéia. É divertido, porém, sempre. Agora que temos alguns números de linha de base para uma idéia de escala, vejamos como fazemos essas páginas web extravagantes. Uma vez que poucos sistemas existem em completo isolamento (e o nosso não é uma exceção), decisões de arquitetura muitas vezes fazem muito menos sentido sem uma imagem maior de como essas peças se encaixam no todo. Essa é a meta aqui, para cobrir o grande quadro. Muitas postagens subseqüentes farão mergulhos profundos em áreas específicas. Esta será uma visão geral logística com os destaques de hardware apenas a próxima publicação terá os detalhes do hardware. Para aqueles de vocês aqui para ver o que o hardware parece desses dias, aqui estão algumas fotos que tirei do rack A (ele tem um rack irmão compatível B) durante nossa atualização de fevereiro de 2015: e se você estiver nesse tipo de coisa, heres O álbum inteiro de 256 imagens daquela semana (você está malditamente certo que números intencional). Agora, vamos cavar no layout. Heres uma visão lógica dos principais sistemas em jogo: Regras de chão Aqui estão algumas regras que se aplicam globalmente, então eu não tenho que repeti-las com todas as configurações: tudo é redundante. Todos os servidores e equipamentos de rede possuem conectividade de pelo menos 2x 10Gbps. Todos os servidores possuem 2 feeds de energia através de 2 fontes de alimentação de 2 UPS conectadas por 2 geradores e 2 feeds de utilidade. Todos os servidores têm um parceiro redundante entre o rack A e B. Todos os servidores e serviços são duplamente redundantes através de outro data center (Colorado), embora eu principalmente falando sobre Nova York aqui. Tudo é redundante. Os internets Primeiro você tem que nos encontrar o DNS. Encontrar-nos precisa ser rápido, então criamos isso para o CloudFlare (atualmente) porque eles têm servidores DNS mais perto de quase todo mundo ao redor do mundo. Atualizamos nossos registros DNS através de uma API e eles fazem a hospedagem de DNS. Mas, uma vez que foram empurrões com problemas de confiança profundamente enraizados, ainda temos nossos próprios servidores de DNS. Se o apocalipse acontecer (provavelmente causado pela GPL, Punyon ou cache) e as pessoas ainda querem programar para tirar a cabeça dele, bem vire-as. Depois de encontrar o nosso esconderijo secreto, o tráfego HTTP vem de um dos nossos quatro ISPs (Nível 3, Zayo, Cogent e Lightower em Nova York) e flui através de um dos nossos roteadores de quatro curvas. Nós comparamos nossos ISP usando o BGP (bastante padrão) para controlar o fluxo de tráfego e fornecer várias vias para que o tráfego atinja-nos de forma mais eficiente. Esses roteadores ASR-1001 e ASR-1001-X estão em 2 pares, cada um servindo 2 ISPs em modo ativo que também era redundante aqui. Embora eles estejam todos na mesma rede física de 10 Gbps, o tráfego externo está em VLANs independentes isoladas separadas, as quais os balanceadores de carga também estão conectados. Depois de fluir pelos roteadores, você vai para um balanceador de carga. Suponho que este seja um bom momento para mencionar que temos um MPLS de 10Gbps entre nossos 2 centros de dados, mas não está diretamente envolvido no atendimento aos sites. Usamos isso para replicação de dados e recuperação rápida nos casos em que precisamos de uma explosão. Mas Nick, isso não é redundante Bem, você está tecnicamente correto (o melhor tipo de correto), é um único ponto de falha no rosto. Mas espere. Nós mantemos 2 rotas OSPF mais failover (o MPLS é 1, estes são 2 e 3 por custo) através de nossos ISPs. Cada um dos conjuntos mencionados anteriormente se conecta ao conjunto correspondente no Colorado, e eles carregam o tráfego do saldo entre na situação de failover. Podemos fazer com que ambos os conjuntos se conectem a ambos os conjuntos e tenham 4 caminhos, mas, bem, seja o que for. Se movendo. Load Balancers (HAProxy) Os balanceadores de carga estão executando HAProxy 1.5.15 no CentOS 7. nosso sabor preferido do Linux. O tráfego TLS (SSL) também é encerrado em HAPROxy. Bem, esteja olhando duro para o HAProxy 1.7 em breve para obter suporte HTTP2. Ao contrário de todos os outros servidores com um link de rede dual LACP de 10Gbps, cada balanceador de carga possui 2 pares de 10Gbps: um para a rede externa e outro para a DMZ. Essas caixas geram 64 GB ou mais de memória para manipular mais eficientemente a negociação SSL. Quando podemos armazenar em cache mais sessões TLS na memória para reutilização, há menos para recalcular as conexões subseqüentes com o mesmo cliente. Isso significa que podemos retomar as sessões de forma mais rápida e mais barata. Dado que a RAM é bastante econômica em dólares, é uma escolha fácil. Os próprios equilibradores de carga são uma configuração bastante simples. Nós ouvimos sites diferentes em vários IPs (principalmente para preocupações de certificados e gerenciamento de DNS) e roteio para vários backends baseados principalmente no cabeçalho do host. As únicas observações que fazemos aqui são limitantes de taxa e algumas capturas de cabeçalho (enviadas do nosso nível web) para a mensagem HAProxy syslog para que possamos gravar métricas de desempenho para cada solicitação. Bem cobre isso mais tarde também. Web Tier (IIS 8.5, ASP. Net MVC 5.2.3 e. Net 4.6.1) Os balanceadores de carga alimentam o tráfego para 9 servidores que nos referimos como primários (01-09) e 2 devmeta (10-11, nosso ambiente de teste ) Servidores web. Os servidores primários executam coisas como Stack Overflow, Carreiras e todos os sites do Stack Exchange, exceto meta. stackoverflow e meta. stackexchange. Que são executados nos últimos 2 servidores. O aplicativo QampA primário em si é multi-inquilino. Isso significa que um único aplicativo atende os pedidos para todos os sites QampA. Dito de outra forma: podemos executar toda a rede QampA fora de um único conjunto de aplicativos em um único servidor. Outras aplicações como Careers, API v2, Mobile API, etc. são separadas. É o que são os níveis primário e dev no IIS: Heres sobre o que a distribuição da Stack Overflows na web é semelhante ao Opserver (nosso painel de controle interno): e o que esses servidores web se parecem com uma perspectiva de utilização: eu entendo por que estava Tão superprovisionados em postagens futuras, mas os itens em destaque são: compilações contínuas, espaço livre e redundância. Nível de serviço (IIS, ASP. Net MVC 5.2.3. Net 4.6.1 e HTTP. SYS) Atrás desses servidores web é o nível de serviço muito semelhante. Também está executando o IIS 8.5 no Windows 2012R2. Este nível executa serviços internos para suportar o nível de web de produção e outros sistemas internos. Os dois grandes jogadores aqui são Stack Server, que executa o mecanismo tag e é baseado em http. sys (não por trás do IIS) e Providence API (baseado em IIS). Fato divertido: eu tenho que definir afinidade em cada um desses dois processos para aterrar em soquetes separados, pois o Stack Server apenas faz o SteamL2 e o L3 ao atualizar listas de perguntas em um intervalo de 2 minutos. Essas caixas de serviço fazem levantamento pesado com a tag engine e backend APIs onde precisamos de redundância, mas não 9x redundância. Por exemplo, carregar todas as postagens e suas tags que mudam a cada n minutos do banco de dados (atualmente 2) não são tão baratos. Nós não queremos fazer essa carga 9 vezes no nível da web 3 vezes é suficiente e nos dá segurança suficiente. Também configuramos essas caixas de forma diferente no lado do hardware para serem melhor otimizadas para as diferentes características de carga computacional do motor de etiquetas e trabalhos de indexação elástica (que também são executados aqui). O motor de tag é um tópico relativamente complicado em si e será uma publicação dedicada. O básico é: quando você visita questiontaggedjava. Você está batendo no motor da etiqueta para ver quais as perguntas que combinam. Ele faz toda a nossa correspondência de tags fora da pesquisa. Então a nova navegação. Etc., todos estão usando este serviço para dados. Cache amp PubSub (Redis) Usamos o Redis para algumas coisas aqui e sua sólida sólida. Apesar de fazer cerca de 160 bilhões de operações por mês, cada instância está abaixo de 2 CPU. Geralmente muito mais baixo: temos um sistema de cache L1L2 com Redis. L1 é HTTP Cache nos servidores web ou qualquer aplicativo está em jogo. L2 está recuando para Redis e recuperando o valor. Nossos valores são armazenados no formato Protobuf. Via protobuf-dot-net por Marc Gravell. Para um cliente, estavam usando StackExchange. Redis escrito em casa e código aberto. Quando um servidor web recebe uma falta de cache em L1 e L2, ele extrai o valor da fonte (uma consulta de banco de dados, chamada de API, etc.) e coloca o resultado no cache local e no Redis. O próximo servidor que deseja o valor pode perder L1, mas encontraria o valor em L2Redis, salvando uma consulta de banco de dados ou chamada de API. Nós também executamos muitos sites QampA, então cada site possui seu próprio cache L1L2: por prefixo de chave em L1 e por ID de banco de dados em L2Redis. Bem, aprofundar isso em uma publicação futura. Juntamente com os 2 servidores Redis principais (masterview) que executam todas as instâncias do site, também temos uma instância de aprendizado de máquina escravizada em mais 2 servidores dedicados (devido à memória). Isso é usado para recomendar perguntas na página inicial, melhor correspondência para trabalhos, etc. É uma plataforma chamada Providence, coberta por Kevin Montrose aqui. Os principais servidores Redis possuem 256 GB de RAM (cerca de 90 GB em uso) e os servidores Providence possuem 384 GB de RAM (cerca de 125 GB em uso). Redis não é apenas para o cache, porém, ele também possui um mecanismo de assinante de amplificador de publicação, onde um servidor pode publicar uma mensagem e todos os outros assinantes recebem os clientes a jusante em escravos Redis. Usamos esse mecanismo para limpar caches L1 em outros servidores quando um servidor web faz uma remoção para consistência, mas há outro ótimo uso: websockets. Websockets (NetGain) Usamos websockets para empurrar atualizações em tempo real para usuários, como notificações na barra superior, contagem de votos, novas contagens de nav, novas respostas e comentários e alguns outros bits. Os próprios servidores de soquete usam sockets brutos executados no nível da web. É uma aplicação muito fina na nossa biblioteca de código aberto: StackExchange. NetGain. Durante o pico, temos cerca de 500.000 conexões concorrentes de websocket abertas. Isso é um monte de navegadores. Fato divertido: alguns desses navegadores estão abertos há mais de 18 meses. Não tinha certeza do porquê. Alguém deveria verificar se esses desenvolvedores ainda estão vivos. É o que esta semana o padrão de websocket concorrente se parece: Por que os websockets são tremendamente mais eficientes do que as pesquisas em nossa escala. Podemos simplesmente empurrar mais dados com menos recursos desta forma, sendo mais instantâneos para o usuário. Eles não estão sem problemas, a porta e o esgotamento do comando de arquivos no balanceador de carga são problemas divertidos, bem, cobrem mais tarde. Pesquisa (Elasticsearch) Spoiler: não há muito para se entusiasmar por aqui. O nível da web está fazendo belas pesquisas de baquelas contra o Elasticsearch 1.4, usando o muito fino cliente StackExchange. Elastic de alto desempenho. Ao contrário da maioria das coisas, não temos planos de abrir esta fonte simplesmente porque ela apenas expõe um subconjunto muito fino da API que usamos. Eu acredito firmemente que liberar isso faria mais mal do que bem com a confusão do desenvolvedor. Usamos elástico para pesquisa. Calculando questões relacionadas e sugestões ao fazer uma pergunta. Cada cluster Elastic (há um em cada centro de dados) tem 3 nós, e cada site possui seu próprio índice. Carreiras tem alguns índices adicionais. O que torna nossa configuração um pouco não padronizada no mundo elástico: nossos 3 clusters de servidores são um pouco mais robustos do que a média com todo o armazenamento SSD, 192GB de RAM e rede dual de 10Gbps cada. Os mesmos domínios de aplicação (sim, foram ferrados com. Net Core aqui) no Servidor de pilha que hospedam o mecanismo de tag também indexam continuamente itens na Elasticsearch. Nós fazemos alguns truques simples aqui, como ROWVERSION no SQL Server (a fonte de dados) em comparação com um documento de última posição em Elastic. Uma vez que se comporta como uma seqüência, podemos simplesmente pegar e indexar todos os itens que mudaram desde a última passagem. O motivo principal foi no Elasticsearch em vez de algo como pesquisa de texto completo em SQL é escalabilidade e melhor alocação de dinheiro. As CPUs SQL são comparativamente muito caras, o Elastic é barato e tem muito mais recursos nos dias de hoje. Por que não Solr. Queremos pesquisar em toda a rede (muitos índices ao mesmo tempo), e isso não foi suportado no momento da decisão. O motivo não estava em 2.x ainda é uma mudança importante nos tipos significa que precisamos reindexar tudo para atualizar. Eu simplesmente não tenho tempo suficiente para fazer as mudanças e o plano de migração necessários ainda. Bancos de dados (SQL Server) Usavam o SQL Server como nossa única fonte de verdade. Todos os dados em Elastic e Redis vêm do SQL Server. Executamos 2 clusters do SQL Server com grupos de disponibilidade AlwaysOn. Cada um desses clusters tem 1 mestre (tendo quase toda a carga) e 1 réplica em Nova York. Além disso, eles têm uma réplica no Colorado (nosso centro de dados DR). Todas as réplicas são assíncronas. O primeiro cluster é um conjunto de servidores Dell R720xd, cada um com 384 GB de RAM, 4 TB de espaço PCIe SSD e 2 x 12 núcleos. Ele hospeda os bancos de dados da pilha, dos sites (nome incorreto, explicam mais tarde), PRIZM e Mobile. O segundo cluster é um conjunto de servidores Dell R730xd, cada um com 768GB de RAM, 6TB de espaço PCIe SSD e 2x 8 núcleos. Este cluster corre tudo o resto. Essa lista inclui Carreiras. Abrir ID. Bate-papo. Nosso log Exception. E qualquer outro site QampA (por exemplo, Usuário Super. Falha no Servidor, etc.). A utilização da CPU na camada do banco de dados é algo que gostamos de manter muito baixo, mas, na verdade, é um pouco alto no momento, devido a alguns problemas de cache do plano foram abordados. A partir de agora, NY-SQL02 e 04 são mestres, 01 e 03 são réplicas que acabamos de reiniciar hoje durante algumas atualizações SSD. É o que as últimas 24 horas se parecem: Nosso uso de SQL é bastante simples. O simples é rápido. Embora algumas consultas possam ser loucas, nossa interação com o próprio SQL é justamente uma baunilha. Temos algum legacy Linq2Sql. Mas todo o novo desenvolvimento está usando o Dapper. Nosso micro-ORM de código aberto usando POCOs. Deixe-me colocar isso de outra forma: o Depósito de pilha tem apenas 1 procedimento armazenado no banco de dados e pretendo mover esse último vestígio para o código. Ok, vamos mudar as mudanças para algo que possa ajudá-lo mais diretamente. Eu mencionei alguns destes acima, mas eu forneço uma lista aqui de muitas bibliotecas. Net de código aberto que nós mantemos para o mundo usar. Nós abrimos porque eles não têm valor comercial básico, mas podem ajudar o mundo dos desenvolvedores. Espero que você ache estes úteis hoje: Dapper (.Net Core) - Micro-ORM de alto desempenho para ADO. Net StackExchange. Redis - Cliente Redis de alto desempenho MiniProfiler - Profiler leve que corremos em cada página (também suporta Ruby, Go, E Nó) Excepcional - Registro de erros para SQL, JSON, MySQL, etc. Jil - Serializador JSON (de) serial de alto desempenho Sigil - A. Net Assistente de geração CIL (para quando C é suficientemente rápido) NetGain - Servidor websocket de alto desempenho Opserver - Acompanhamento do painel que polling a maioria dos sistemas diretamente e alimentação de Orion, Bosun ou WMI também. Bosun - Sistema de monitoramento Backend, escrito em Go Next up é uma lista detalhada de hardware atual do que executa o nosso código. Depois disso, descemos a lista. Fique ligado. Por favor, ative o JavaScript para visualizar os comentários alimentados por Disqus.
No comments:
Post a Comment