Para un caso simple como este, elegiría el que se vea mejor en cuanto a código.
Hay algunos casos en los que es recomendable llamar una vez y leer el valor de retorno salvado, como por ejemplo en
for (int i = 0; i < list.size(); i++)
doSomethingThatDoesNotAffectSizeOfList();
ya que el compilador puede tener problemas para averiguar si el cuerpo del bucle afecta al tamaño de la lista. Una lista se implementa correctamente siempre debe ser capaz de decirle a su tamaño con facilidad, pero en otros ejemplos (o cuando se trata de colecciones mal implementados) que podría ser peor.
En general, si un método es computacionalmente pesado, puede usar memoization, lo que básicamente significa que almacena en caché los valores de entrada/salida ya computados.
Una función memorizada "recuerda" los resultados correspondientes a un conjunto de entradas específicas. Las llamadas posteriores con entradas recordadas devolver el resultado recordado que en vez de recalcular, eliminando así el coste principal de una llamada con los parámetros dados de todo pero la primera llamada realizada a la función con esos parámetros.
Esta técnica empuja el "salvar-la-vuelta-relación calidad-eficiencia" en el método en sí, lo que facilita el mantenimiento bla bla bla ...
Un tema bastante similar (aunque relacionado con C++) fue discutido recientemente en SO, ver http://stackoverflow.com/questions/2753381/ - quizás algunas de las respuestas expresadas allí también sean útiles para usted. – stakx