T1: Quais ferramentas você está usando para criação de perfil de código (criação de perfil, não avaliação de desempenho)?
P2: quanto tempo você deixa o código executar (estatísticas: quantas etapas de tempo)?
Q3: Qual é o tamanho dos casos (se o caso couber no cache, o solucionador é de ordens de magnitude mais rápido, mas sentirei falta dos processos relacionados à memória)?
Aqui está um exemplo de como eu faço isso.
Separei o benchmarking (vendo quanto tempo leva) do perfil (identificando como torná-lo mais rápido). Não é importante que o criador de perfil seja rápido. É importante que ele lhe diga o que corrigir.
Eu nem gosto da palavra "criação de perfil" porque evoca uma imagem como um histograma, onde há uma barra de custo para cada rotina ou "gargalo" porque implica que há apenas um pequeno local no código que precisa ser fixo. Ambas as coisas implicam algum tipo de tempo e estatística, para os quais você assume que a precisão é importante. Não vale a pena abrir mão da percepção da precisão do tempo.
O método usado é uma pausa aleatória, e há um estudo de caso completo e uma apresentação de slides aqui . Parte da visão de mundo dos gargalos do criador de perfil é que, se você não encontrar nada, não há nada a ser encontrado, e se você encontrar algo e obter uma certa porcentagem de aceleração, declara vitória e sai. Os fãs do Profiler quase nunca dizem quanta aceleração recebem, e os anúncios mostram apenas problemas artificialmente criados para serem fáceis de encontrar. A pausa aleatória encontra os problemas, sejam eles fáceis ou difíceis. A solução de um problema expõe outros, para que o processo possa ser repetido, para aumentar a velocidade.
Na minha experiência com vários exemplos, veja como ele funciona: posso encontrar um problema (pausando aleatoriamente) e corrigi-lo, obtendo uma aceleração de alguns por cento, digamos 30% ou 1,3x. Então eu posso fazer isso de novo, encontrar outro problema e corrigi-lo, obtendo outro aumento de velocidade, talvez menos de 30%, talvez mais. Então eu posso fazê-lo novamente, várias vezes, até realmente não encontrar mais nada para consertar. O fator de aceleração final é o produto em execução dos fatores individuais e, em alguns casos, pode ser incrivelmente grande - ordens de magnitude.
INSERIDO: Apenas para ilustrar este último ponto. Há um exemplo detalhado aqui , com apresentação de slides e todos os arquivos, mostrando como uma aceleração de 730x foi alcançada em uma série de remoções de problemas. A primeira versão levou 2700 microssegundos por unidade de trabalho. O problema A foi removido, diminuindo o tempo para 1800 e ampliando as porcentagens de problemas restantes em 1,5x (2700/1800). Então B foi removido. Esse processo continuou por seis iterações, resultando em quase três ordens de aceleração de magnitude. Mas a técnica de criação de perfil deve ser realmente eficaz, porque se nenhum desses problemas for encontrado, ou seja, se você chegar a um ponto em que você pensa incorretamente que nada mais pode ser feito, o processo será interrompido.
INSERIDO: Dito de outra maneira, aqui está um gráfico do fator de aceleração total à medida que problemas sucessivos são removidos:
Assim, no primeiro trimestre, para o benchmarking basta um temporizador simples. Para "criação de perfil", uso uma pausa aleatória.
Q2: Eu ofereço carga de trabalho suficiente (ou apenas coloco um loop em torno dela) para que ela demore o suficiente para fazer uma pausa.
Q3: De qualquer forma, ofereça uma carga de trabalho realisticamente grande para não perder problemas de cache. Eles aparecerão como exemplos no código que faz a busca na memória.