Euler № 211 проекта - проблема эффективности

Я хотел бы понять, как влияют на память и производительность одиночные и внедренные сервисы в Angular 7.

blockquote>

Зависимости в Angular обрабатываются через провайдеров. Существует много типов поставщиков, таких как постоянные значения, фабрики, классы и т. Д. И т. Д.

Служба относится к инъецируемому классу, для которого был создан экземпляр. Когда создается , зависит от , когда ему предоставляется , предоставляется . Наиболее распространенным местом для объявления провайдера является объявление модуля . Таким образом, мы называем это областью действия провайдера.

Поставщик по умолчанию является одиночным распознавателем значения , но можно настроить поставщика как кратное . Для простоты мешков давайте предположим, что провайдеры - это одиночки в рамках.

Область может иметь родительских и детей . Когда провайдер объявляется , он предоставляется в текущей области . Модули имеют тенденцию быть очень высоко на дереве инжекторов с корнем наверху.

Когда создается компонент, мы можем думать об этом как о новой области видимости. С компонентом начальной загрузки в верхней части дерева компонентов, но с учетом того, что вы можете использовать фабрику для создания нового компонента, это означает, что вы не должны предполагать, что все является частью одного и того же дерева.

Да, это может быть сложно.

Например, предположим, что у меня есть список компонентов на странице, и каждому из них добавляется одна и та же услуга (т. е. она указана в поставщиках компонентов).

blockquote>

Давайте предположим, что эта служба называется FooBarService. Я могу объяснить множество разных вещей, которые могут произойти, основываясь на том, как вы настроили инжектор зависимостей.

  1. Инжектор выдаст ошибку, что FooBarService является неизвестной зависимостью.
  2. Корневой модуль предоставил FooBarService, и этот компонент и все другие компоненты получат тот же экземпляр.
  3. Модуль с отложенной загрузкой предоставил FooBarService, и этот компонент получит экземпляр, но компоненты вне модуля с отложенной загрузкой будут выдавать ошибку неизвестной зависимости.
  4. Родительский компонент предоставил FooBarService, и все его дочерние компоненты получат экземпляр.
  5. Каждый компонент предоставил FooBarService, и каждый компонент получает новый экземпляр.

Поскольку вы указали «он указан в поставщиках компонентов», тогда будет применяться опция № 5.

См. Эту ссылку: https://angular.io/guide/providers#providing-services-in-modules-vs-components

Означает ли это, что если У меня есть например Для 50 компонентов мне понадобится в 50 раз больше требований к памяти для внедренной службы, чем для единой службы, которая является общей для всех?

blockquote>

Да, если вы объявили поставщика в области действия компонента а не объем модуля. Для каждого компонента, который объявил его, будет один экземпляр, но этот экземпляр является общим для дочерних элементов этого компонента.

Есть ли какие-либо другие факторы, влияющие на производительность?

blockquote>

Да, требуется больше памяти и времени для создания 50 компонентов, если инжектор должен создавать новые экземпляры. Повлияет ли это на ваше программное обеспечение? Как и в случае любого решения, это зависит от того, почему вы это делаете. Если это должно решить проблему зависимости, то это может быть единственным способом сделать это. Если бы вы могли вместо этого использовать общий синглтон-сервис, я бы удивился, почему вы этого не сделали.

5
задан iCodez 22 January 2015 в 16:15
поделиться

7 ответов

Вот решение, имея в виду дух Euler [Проекта]. [Предупреждение: спойлер. Я попытался сохранить подсказки медленными, так, чтобы Вы могли часть только для чтения ответа и думать самостоятельно, если Вы хотите.:)]

То, когда Вы сталкиваетесь с проблемой, имеющей отношение к числам, одна хорошая стратегия (как Вы, вероятно, уже знаете от решения 210 Euler проблем Проекта), должно посмотреть на небольшие примеры, найти шаблон и доказать его. [Последняя часть может быть дополнительной в зависимости от Вашего отношения к математике ;-)]

В этой проблеме, тем не менее, смотрящей на небольшие примеры - для n=1,2,3,4... вероятно, не даст Вам подсказки. Но существует другой смысл "небольших примеров" при контакте с теоретическими числом проблемами, которые Вы также, вероятно, знаете к настоящему времени - начала являются стандартными блоками натуральных чисел, поэтому запустите с начал.

Для простого числа p его единственные делители равняются 1 и p, таким образом, сумма квадратов его делителей 1+p2.
Для главного питания pk, его единственные делители равняются 1, p, p2, … pk, таким образом, сумма квадратов ее делителей 1+p+p2 + … + pk = (pk+1-1) / (p-1).
Это было самым простым случаем: Вы решили проблему для всех чисел только с одним простым множителем.

До сих пор ничто специальное. Теперь предположите, что у Вас есть номер n, который имеет два простых множителя, скажите n=pq. Затем его факторы равняются 1, p, q, и pq, таким образом, сумма квадратов ее делителей 1+p2+q2+p2q2 = (1+p2) (1+q2).
Что относительно n=paqb? Какова сумма квадратов ее факторов?

[............................ Опасный для чтения ниже этой строки...................]

Это - −0≤c≤a, 0≤d≤b (pcqd) 2 = ((pa+1-1) / (p-1)) ((qb+1-1) / (q-1)).

Это должно дать Вам подсказку, и на том, что ответ и как доказать его: сумма делителей n является просто продуктом (ответ) для каждого из главных полномочий в его факторизации, таким образом, все, что необходимо сделать, должно разложить на множители 64000000 (который очень легко сделать даже в голове и умножить ответ для каждого (=both, потому что единственные начала равняются 2 и 5) его главных полномочий.

Это решает Euler проблему Проекта; теперь мораль для отнимания у него.

Более общий факт здесь о мультипликативных функциях - функционирует на натуральных числах, таким образом, что f (млн) = f (m) f (n) каждый раз, когда у GCD (m, n) =1, т.е. m и n не есть общие простые множители. Если у Вас есть такая функция, значение функции в конкретном числе полностью определяется его значениями в главных полномочиях (можно ли доказать это?)

Немного более трудный факт, который можно попытаться доказать [дело не в этом трудно], является этим: если у Вас есть мультипликативная функция f [здесь, f (n) =n2], и Вы определяете функцию F, поскольку F (n) = −d делит nf (d), (как проблема сделала здесь), затем F (n), также мультипликативная функция.

[На самом деле что-то очень красивое верно, но просто еще не смотрите на него, и Вам, вероятно, никогда не будет нужно оно.:-)]

14
ответ дан 18 December 2019 в 07:11
поделиться

Я думаю, что Ваш алгоритм не является самым эффективным. Подсказка: можно запускать с неправильной стороны.

править: Я хотел бы добавить, что при выборе 64000000, поскольку верхний предел вероятен проблемный плакат способ сказать Вам думать о чем-то лучше.

править: Несколько подсказок эффективности:

  • вместо
(setf l (append l (...)))

можно использовать

(push (...) l)

который пагубно изменяет Ваш список путем концентрирования новой ячейки со значением как автомобиль и первый l как CDR, затем указывает l к этой ячейке. Это намного быстрее, чем добавление, которое должно пересечь список однажды каждый. При необходимости в списке в другом порядке Вы можете nreverse он после того, как это завершено (но это не нужно здесь).

  • почему Вы сортируете l?

  • можно сделать (> current (/ num current)) более эффективный путем сравнения квадратному корню цифры вместо этого (который только должен быть вычислен однажды на цифру).

  • возможно, возможно найти факторы числа более эффективно?

И подсказка стиля: можно поместить объем l в делают объявление:

(do ((l ())
     (current 1 (+ current 1)))
    ((> current (/ num current))
     l)
  ...)
3
ответ дан 18 December 2019 в 07:11
поделиться

Умный прием, который Вы пропускаете, - то, что Вы не должны учитывать числа вообще Сколько чисел от 1.. N являются кратными числами 1? N, Сколько чисел от 1.. N являются кратными числами 2? N/2

Прием должен суммировать факторы каждого числа в списке. Для 1, добавьте 1^2 к каждому числу в списке. Для 2, добавьте 2^2 к любому числу. Для 3, добавьте 3^2 к каждому 3-му числу.

Не проверяйте на делимость вообще. В конце действительно необходимо проверить, является ли сумма полным квадратом, и вот именно. В C++ это работало за 58 секунд на меня.

2
ответ дан 18 December 2019 в 07:11
поделиться

Я напал бы на это путем выполнения главной факторизации числа (например: 300 = 2^2 * 3^1 * 5^2), который относительно быстр, особенно если Вы генерируете это решетом. От этого относительно просто генерировать факторы путем итерации i=0.. 2; j=0.. 1; k=0.. 2, и выполнение 2^i * 3^j * 5^k.

5 3 2
-----
0 0 0 = 1
0 0 1 = 2
0 0 2 = 4
0 1 0 = 3
0 1 1 = 6
0 1 2 = 12
1 0 0 = 5
1 0 1 = 10
1 0 2 = 20
1 1 0 = 15
1 1 1 = 30
1 1 2 = 60
2 0 0 = 25
2 0 1 = 50
2 0 2 = 100
2 1 0 = 75
2 1 1 = 150
2 1 2 = 300

Это не могло бы быть достаточно быстро

2
ответ дан 18 December 2019 в 07:11
поделиться

Извините, я не понимаю LISP достаточно хорошо для чтения ответа. Но мое первое впечатление - то, что стоимость времени решения для грубой силы должна быть:

открытая скобка

sqrt (k), чтобы найти делители k (испытательным подразделением), квадрат каждый (постоянное время на фактор), и суммировать их (постоянное время на фактор). Это - σ2 (k), который я назову x.

плюс

не уверенный, какова сложность хорошего целочисленного алгоритма квадратного корня, но конечно не хуже, чем sqrt (x) (немое испытательное умножение). x мог бы хорошо быть большой-O больше, чем k, таким образом, я резервирую решение здесь, но x, очевидно, ограничен выше k^3, потому что k имеет в большинстве k делителей, каждый сам не больше, чем k и следовательно его квадрат, не больше, чем k^2. Это было таким длинным начиная с моего градуса математики, что я понятия не имею, как быстрый Ньютон-Raphson сходится, но я подозреваю, что это быстрее, чем sqrt (x), и если все остальное перестало работать, поиск делением пополам является журналом (x).

закрывающая квадратная скобка

умноженный на n (поскольку k располагается 1.. n).

Таким образом, если Ваш алгоритм хуже, чем O (n * sqrt (n^3)) = O (n ^ (5/2)) в немом-sqrt случае или O (n * (sqrt (n) + журнал (n^3)) = O (n ^ 3/2) в умном-sqrt случае, я думаю, что что-то пошло не так, как надо, который должен идентифицироваться в алгоритме. В этой точке я застреваю, потому что я не могу отладить Ваш LISP.

О, я предположил, что арифметика является постоянно-разовой для используемых чисел. Это чинит, хорошо должны быть для чисел всего 64 миллиона, и куб этого помещается в целое число без знака на 64 бита, едва. Но даже если Ваша реализация LISP делает арифметику хуже, чем O (1), это не должно быть хуже, чем O (зарегистрируйте n), таким образом, это не будет иметь большого влияния на сложности. Конечно, не сделает это супермногочленом.

Это - то, где кто-то приезжает и говорит мне, как неправильно я.

Ой, я просто посмотрел на Ваши фактические фигуры синхронизации. Они не хуже, чем экспоненциал. Игнорирование первых и последних значений (потому что маленькие времена не точно измеримы и Вы не закончили, соответственно), умножаясь n на 10 умножает время на не больше, чем с 30 выходами. 30 о 10^1.5, который является о прямо для грубой силы, как описано выше.

1
ответ дан 18 December 2019 в 07:11
поделиться

Я думаю, что можно приняться за решение этой проблемы с чем-то как главное решето. Это - только мое первое впечатление все же.

0
ответ дан 18 December 2019 в 07:11
поделиться

Я переделал программу с некоторыми заметками, сделанными из комментариев здесь. Функция 'факторов' теперь очень немного более эффективна, и я также должен был изменить σ _ (2) (n) функция для принятия нового вывода.

'факторы' пошли от наличия вывода как:

$ (factors 10) => (1 2 5 10)

к наличию одного как

$ (factors 10) => ((2 5) (1 10))

Пересмотренная функция похожа на это:

(defun o_2 (n)
"sum of squares of divisors"
  (reduce #'+ (mapcar (lambda (x) (* x x)) (reduce #'append (factors n)))))

После того, как скромное переписывает, я сделал, я только сохранил приблизительно 7 секунд в вычислении для 100 000.

Похож я оказываюсь перед необходимостью выходить задницы и писать более прямой подход.

0
ответ дан 18 December 2019 в 07:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: