|
![]() |
#1 |
Участник
|
Написал джоб, который генерирует первые 10 тысяч чисел фибоначчи. Длина 10-тысячного числа составляет около 2000 цифр. Вообще, приблизительная длина любого n-ного числа фибоначчи составляет примерно n/5 цифр. Так как надо сложить 1+2+3+5+8 = 5 чисел, чтобы к числу прибавился новый разряд.
Джоб у меня отработал примерно за 20 минут. На генерацию одного n-ного члена ряда, у которого n близко к 10000, уходит примерно 0,2 секунды. На генерацию первой тысячи элементов ряда уходит 5-10 секунд. Поэтому для удобства тестируйте этот джоб для 1000 элементов. Если переписать этот джоб на языке C++ и пользоваться указателями и массивами, то быстродействие увеличится в тысячи раз. И можно будет вычислять миллионные члены ряда Фибоначчи. X++: static void Job119(Args _args) { int fibonacciSize = 10000; //сколько надо получить чисел Фибоначчи str x; str y; str total; int i; SysOperationProgress p = new SysOperationProgress(); str sumStrings(str _a, str _b) { str ret; int result; int digit; int j; int a; int b; int n; ; for (j = (strLen(_a) > strLen(_b) ? strLen(_a) : strLen(_b)); j >= 1; j--) { n ++; if (strLen(_a) >= n) a = str2int(subStr(_a, strLen(_a) - n + 1, 1)); else a = 0; if (strLen(_b) >= n) b = str2int(subStr(_b, strLen(_b) - n + 1, 1)); else b = 0; result = digit + a + b; digit = result / 10; result = result mod 10; ret = int2str(result) + ret; } if (digit) ret = int2str(digit) + ret; return ret; } ; p.settotal(fibonacciSize); p.update(true); x = "0"; y = "1"; info(x); info(y); while (fibonacciSize) { p.incCount(); p.update(true); fibonacciSize --; total = sumStrings(x, y); info(total); [x, y] = [y, total]; } } Последний раз редактировалось Ace of Database; 11.02.2017 в 15:59. |
|
|
За это сообщение автора поблагодарили: mazzy (2). |
![]() |
#2 |
Участник
|
Цитата:
Цитата:
еще не все из x++ выжато. Предложения по улучшению: 1. вполне достижим результат "меньше 1 минуты". (для измерения скорости можно отказаться от SysOperationProgress) 2. "j = (strLen(_a) > strLen(_b) ? strLen(_a) : strLen(_b))" - фи, моветон. и strlen вычисляется дважды для каждой строки. лучше j = max(strlen(_a), strlen(_b)) 3. операции со строками очень медленные. и сильно нагружают сборщик мусора. лучше использовать массив 4. сложение огромных чисел - это отдельная задача для собеседований ))))) там главная хитрость - оперировать не отдельными цифрами, а группами цифр. в одном int32 легко можно хранить до 9 полноценных разрядов (числа до +2147483647). Что в совокупности с массивом вместо строки, может дать увеличение производительности раз в 10. а ведь есть еще int64 и bigint ))) 5. деление - очень дорогостоящая операция ))) когда исчерпаете варианты оптимизации, попробуйте заменить деление сравнением и сложением/вычитанием. Дополнительный цикл не понадобится ))) 6. особенность x++ - вызов вложенной функции в X++ выполняется непропорционально долго по сравнению с вызовом обычного метода. попробуйте переделать, сами удивитесь. 7. особенность x++ - Конейнер - это сериализация-десериализация. Контейнер очень дорогостоящая операция для банального swap. Попробуйте избавиться от контейнера. ))))) и еще: будете играться с типами int32, int64 попробуйте разные режимы - на клиенте/на сервере. со включенным CIL и с выключенным. это тоже особенность X++ Последний раз редактировалось mazzy; 11.02.2017 в 18:36. |
|
|
За это сообщение автора поблагодарили: alex55 (1). |
![]() |
#3 |
Участник
|
ок, попробую вместо строк использовать массив int64. В ближайшее время, когда почувствую вдохновение
|
|
![]() |
#4 |
Участник
|
|
|