Por que o java não usa uma classificação radix em primitivas?


12

java.util.Arrays.sort(/* int[], char[], short[], byte[], boolean[] */) é implementado como um 'quicksort ajustado' em vez de uma classificação de base.

Fiz uma comparação de velocidade há um tempo atrás e, com algo como n> 10000, a classificação de radix era sempre mais rápida. porque?

Respostas:


17

Eu especularia que:

  • Array.sort é implementado como quicksort, porque quicksort pode classificar qualquer coisa em tempo decente, considerando um comparador.
  • Classificar uma lista de 10000 entradas não é tão comum. Acessar uma estrutura de dados de 10000 ou mais elementos é bastante comum. Se você precisar manter a ordem, uma árvore de pesquisa equilibrada geralmente é o melhor caminho a percorrer do que classificar toda a matriz toda vez que precisar do menor elemento.
  • A classificação de primitivas não é tão comum, apesar do que a universidade pode ensinar.

O ponto é que, não é um caso de uso tão comum, que sua otimização precisa estar na biblioteca padrão. Se você escreveu um aplicativo com problemas de desempenho, em que determina através da criação de perfis que a classificação de uma matriz de mais de 10000 ints é realmente o gargalo, você pode escrever a classificação manualmente ou reconsiderar sua escolha de estrutura de dados no primeiro Lugar, colocar.


Não tenho 100% de certeza, mas acho que o TimSort é usado em alguns casos agora.
Martijn Verburg

1
Mas não existe algo como Array.sort, existem vários Array.sorts, e a pergunta era sobre isso especializado em tipos numéricos.
Danubian Sailor

6

O Back2dos já disse tudo, tentarei esclarecer melhor o ponto que considero mais importante:

A classificação Radix pode classificar apenas os valores primitivos reais contidos na matriz, com base em seus padrões de dígitos binários. Em cenários reais de engenharia de software do mundo real, esse caso é encontrado quase nunca . O que costumamos fazer com mais frequência é ordenar matrizes de estruturas de dados mais complexas (não primitivas) e, algumas vezes, ordenamos matrizes de índices para outras entidades.

Agora, uma matriz de índices para outras entidades é de fato uma matriz de primitivas, mas a ordem de classificação é fornecida pela interface do comparador (e / ou delegado em C #) que compara não os índices, mas as entidades indexadas pelos índices. Portanto, a ordem de classificação não tem absolutamente nenhuma relação com a ordem dos valores das primitivas e, portanto, a classificação de base é absolutamente inútil para esse cenário.

Um exemplo:

Temos uma matriz de cadeias de caracteres: [0] = "Mike", [1] = "Albert", [2] = "Zoro". Em seguida, declaramos uma matriz de índices para essas cadeias: [0] = 0, [1] = 1, [2] = 2. Em seguida, classificamos a matriz de índices, passando a ela um comparador que compara não os próprios índices, mas as seqüências de caracteres reais referidas por esses índices. Após a classificação, a matriz de índices resultante ficará assim: [0] = 1, [1] = 0, [2] = 2. Como você pode ver, essa ordem de classificação não tem nada a ver com os padrões binários dos valores contidos na matriz e, no entanto, percorrendo essa matriz de índices e buscando cada string correspondente, visitamos as strings em ordem classificada.

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.