Como já foi dito, o -cp serve apenas para dizer ao jvm na linha de comando qual classe usar para o thread principal e onde ele pode encontrar as bibliotecas (definir classpath). Em -jar, ele espera que o caminho da classe e a classe principal sejam definidos no manifesto do arquivo jar. Portanto, outro é para definir coisas na linha de comando, enquanto outro é encontrá-los dentro do manifesto jar. Não há diferença no desempenho. Você não pode usá-los ao mesmo tempo, -jar substituirá o -cp.
Embora mesmo se você usar -cp, ele ainda verificará o arquivo de manifesto. Portanto, você pode definir alguns dos caminhos de classe no manifesto e alguns na linha de comando. Isso é particularmente útil quando você tem uma dependência de algum jar de terceiros, que você pode não fornecer com sua compilação ou não deseja fornecer (esperando que já seja encontrado no sistema onde será instalado, por exemplo). Portanto, você pode usá-lo para fornecer jars externos. Sua localização pode variar entre os sistemas ou pode até ter uma versão diferente em um sistema diferente (mas com as mesmas interfaces). Desta forma, você pode construir o aplicativo com outra versão e adicionar a dependência real de terceiros ao caminho de classe na linha de comando ao executá-lo em sistemas diferentes.