Давайте начнем с небольшой переписки вашего кода, например:
int HappyTest()
{
int n;
for (int i = 0; i < 210000000; i++) { // Reduced by a factor 10 compared to OP code
n = i;
while (n >= 10) {
int m = n, sum = 0;
while (m != 0) {
int t = m >= 10 ? m % 10 : m;
sum += t * t;
m /= 10;
}
n = sum;
}
}
return n;
}
int main(void) {
printf("%d\n", HappyTest());
}
Выполнение этого в моей системе занимает 10,7 секунды.
Ваш код примерно такой: возьмите число и вычислитесумма всех его цифр в квадрате.
Таким образом, ваши умножения ограничены 10 различными умножениями, т. Е. 0 * 0, 1 * 1, ..., 9 * 9
Таким образом, одной из идей оптимизации может быть помещение результатов втаблицу и сделать поиск таблицы вместо умножения.Например:
int mul_tab_10[10] = {0, 1, 4, 9, 16, 25, 36, 49, 64, 81};
int HappyTest()
{
int n;
for (int i = 0; i < 210000000; i++) {
n = i;
while (n >= 10) {
int m = n, sum = 0;
while (m != 0) {
int t = m >= 10 ? m % 10 : m;
sum += mul_tab_10[t];
m /= 10;
}
n = sum;
}
}
return n;
}
Выполнение этого в моей системе занимает 12,9 секунды.Так что это медленнее .
Но что, если мы сделаем этот шаг еще дальше?Вместо того, чтобы просто использовать таблицу с 10 элементами, мы могли бы использовать таблицу с 100 элементами.Как:
int mul_tab_100[100] = {0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 1, 2, 5, 10, 17, 26, 37, 50, 65, 82, 4, 5, 8, 13, 20, 29, 40, 53, 68, 85, 9, 10, 13, 18, 25, 34, 45, 58, 73, 90, 16, 17, 20, 25, 32, 41, 52, 65, 80, 97, 25, 26, 29, 34, 41, 50, 61, 74, 89, 106, 36, 37, 40, 45, 52, 61, 72, 85, 100, 117, 49, 50, 53, 58, 65, 74, 85, 98, 113, 130, 64, 65, 68, 73, 80, 89, 100, 113, 128, 145, 81, 82, 85, 90, 97, 106, 117, 130, 145, 162};
int HappyTest()
{
int n;
for (int i = 0; i < 210000000; i++) {
n = i;
while (n >= 10) {
int m = n, sum = 0;
while (m != 0) {
int t = m >= 100 ? m % 100 : m; // Notice this change
sum += mul_tab_100[t];
m /= 100; // Notice this change
}
n = sum;
}
}
return n;
}
Выполнение этого в моей системе занимает 6,9 секунды.Таким образом, производительность улучшена .
Если сделать еще один шаг вперед (т. Е. 1000 элементов), результат составит 5,3 секунды - опять же улучшение .
Такда, вы можете улучшить производительность во время выполнения.