Если коротко, то проблема в том, что один длинный цикл выполняется медленнее, чем несколько аналогичных коротких.
Я транслирую в триады некое арифметическое выражение и потом его считаю. Выражениние большое (гигабайты), но является "механической" суммой тысяч более простых, то есть, просто эти более простые при помощи знака "+" конкатенированы. Пример:
4*x[1]*x[2]- p(3*x[2] + 3*x[1]*x[2] + x[2]*x[3], -4)/648 + l(x[3]*x[5])+(x[1]*x[4] -x[2])/(x[1]*x[3]-125);
просто "механическая" сумма двух коротких:
4*x[1]*x[2]- p(3*x[2] + 3*x[1]*x[2] + x[2]*x[3], -4)/648;
и
l(x[3]*x[5])+(x[1]*x[4] -x[2])/(x[1]*x[3]-125);
(кому интересно, тут x[] -- массив double, p(a,b) -- a в степени b, l(a)-- логарифм, все константы -- double).
При трансляции проводится оптимизация подвыражений, так что, казалось бы, чем выражение длиннее, тем оно должно быстрее считаться, поскольку триад меньше получается. Но это не так, начиная с некоторого момента считается дольше. Например, выражение изначально содержит 644698410 операций, и представлено в виде:
Первый раз 10 файлов размером от 34 MB до полутора GB.
Второй раз 21271 файлов размером от 136 байт до полутора MB.
После оптимизации подвыражений число операций:
Первый раз 27225617
Второй раз 40982442
То есть, во втором случае кол-во требуемых операций в полтора раза больше.
Суммарное время вычисления:
Первый раз 0.3614 секунды
Второй раз 0.1752 секунды
С чем это может быть связано?