|
Как вычислить последовательность накопленных средних с помощью встроенных функций?
|
|||
---|---|---|---|
#18+
Под последовательностью накопленных средних я имею ввиду последовательность: 1) равную входящей последовательности по числу элементов; 2) в которой каждый текущий элемент получается нахождением среднеарифметического всех элементов с начала входящей последовательности по её текущий элемент. Т. е. если А и В - соответственно входящая последовательность и последовательность накопленных средних относительно входящей, то 1) А.Count == B.Count; 2) В[i] = (А[0]+А[1]+... +А[i]) / (i+1). Я это сделал с помощью обычного for, а теперь хочу узнать, как это можно сделать с помощью встроенных функций, типа Enumerable.Aggregate, Enumerable.Sum. Вот мой код для обычного цикла for Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.
... |
|||
:
Нравится:
Не нравится:
|
|||
29.11.2012, 14:13 |
|
Как вычислить последовательность накопленных средних с помощью встроенных функций?
|
|||
---|---|---|---|
#18+
user7320, Что-то в духе Код: c# 1.
...к примеру. ... |
|||
:
Нравится:
Не нравится:
|
|||
29.11.2012, 14:50 |
|
Как вычислить последовательность накопленных средних с помощью встроенных функций?
|
|||
---|---|---|---|
#18+
Abstractionuser7320, Что-то в духе Код: c# 1.
...к примеру. Кашмар. Код: c# 1. 2. 3. 4. 5. 6.
... |
|||
:
Нравится:
Не нравится:
|
|||
29.11.2012, 19:58 |
|
Как вычислить последовательность накопленных средних с помощью встроенных функций?
|
|||
---|---|---|---|
#18+
ЕвгенийВ, спасибо. А ещё узнать хотел бы, какой способ всё же быстрее - мой через for, или ваш через лямбды? А то тут читал, что всякие анонимные методы и их родственники (как я понял) где-то на порядок медленнее, чем непосредственный вызов метода и, как я понимаю, ещё медленнее, если без всяких методов в for прогнать массив со взятием элементов по индексу (особенно, если ещё упростить cumulativeAverage = (cumulativeAverage * i + source[i]) / (i + 1); cumulativeAverages.Add(cumulativeAverage); до cumulativeAverage += source[i]; cumulativeAverages.Add(cumulativeAverage / (i + 1)); ... |
|||
:
Нравится:
Не нравится:
|
|||
29.11.2012, 20:37 |
|
Как вычислить последовательность накопленных средних с помощью встроенных функций?
|
|||
---|---|---|---|
#18+
Выше cumulativeAverage уже станет просто cumulative. ... |
|||
:
Нравится:
Не нравится:
|
|||
30.11.2012, 06:06 |
|
Как вычислить последовательность накопленных средних с помощью встроенных функций?
|
|||
---|---|---|---|
#18+
Несомненно через лямбды медленнее из за вызова делегатов. Но при использовании лябмд, результат будет считаться только когда его кто то запросит, при использовании for он будет считаться всегда. Плюс при использовании for есть накладные расходы на создание List<double> cumulativeAverages, как по памяти, так и по вычислениям. С использованием лямбд можно получить очень большие последовательности(бесконечные), на которые в классическом случае не хватит памяти. Также лямбды в ряде случаев можно легко распараллелить(не в Вашем, так как последующий элемент зависит от предыдущих). ... |
|||
:
Нравится:
Не нравится:
|
|||
30.11.2012, 10:52 |
|
Как вычислить последовательность накопленных средних с помощью встроенных функций?
|
|||
---|---|---|---|
#18+
user7320, А Вы попробуйте закрыть мой список и открыть его снова, результаты будут опять другие))) ... |
|||
:
Нравится:
Не нравится:
|
|||
30.11.2012, 17:12 |
|
Как вычислить последовательность накопленных средних с помощью встроенных функций?
|
|||
---|---|---|---|
#18+
ЕвгенийВuser7320, А Вы попробуйте закрыть мой список и открыть его снова, результаты будут опять другие))) Начнет считать с последнего присвоенного значения sum, а не с нуля. Можно попробовать сделать такую функцию. Код: c# 1. 2. 3. 4. 5.
... |
|||
:
Нравится:
Не нравится:
|
|||
30.11.2012, 17:40 |
|
Как вычислить последовательность накопленных средних с помощью встроенных функций?
|
|||
---|---|---|---|
#18+
ЕвгенийВЕвгенийВuser7320, А Вы попробуйте закрыть мой список и открыть его снова, результаты будут опять другие))) Начнет считать с последнего присвоенного значения sum, а не с нуля. Можно попробовать сделать такую функцию. Код: c# 1. 2. 3. 4. 5.
Так я же говорил, что у меня для каждой суммы своя переменная. Скажем, в лямбде я записываю сумму в sum, а в цикле - в какую-нибудь currentSum. Обе суммы вначале нулём инициализируются. А результат разный. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.12.2012, 07:22 |
|
Как вычислить последовательность накопленных средних с помощью встроенных функций?
|
|||
---|---|---|---|
#18+
Извиняюсь за свою недогадливость - там действительно прицина в том, что значения -640 и т. д. получались после ВТОРОГО вычисления этой лямбды. Дело в том, что я привык, что неиспользованная переменная, даже если ей присвоены какие-то значения, не отображается в дебаге и, по-видимому, вообще не инициализируются средой выполнения. Поэтому добавил после data ещё строку data.ToArray(). Вот она и вычислилась второй раз. Причём она так вычисляется даже если лямбду в функцию положить. Если ToString() сделать, то вычисляется только один раз. Тогда такой вопрос - а что, теперь каждый запрос к переменной, сохраняющей результат вычисления лямбды, вызовет выполнение этой лямбды, причём с запомненным значением её локальных переменных, а не просто считывание данных из переменной результата? Вот те раз! Т. е. чтобы эта лямбда отработала так, как мне нужно, я не должен считывать значения из переменной результата более одного раза? ... |
|||
:
Нравится:
Не нравится:
|
|||
02.12.2012, 08:31 |
|
Как вычислить последовательность накопленных средних с помощью встроенных функций?
|
|||
---|---|---|---|
#18+
Вобщем, чтобы этого избежать, добавил в конце ToList() и эта переменная перестала быть делегатом и стала обычным списком. Теперь можно хоть в массив, хоть что с ней делать - делегат применяться к ней больше не будет. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.12.2012, 09:13 |
|
Как вычислить последовательность накопленных средних с помощью встроенных функций?
|
|||
---|---|---|---|
#18+
user7320 Код: c# 1. 2. 3. 4.
Кажется, это называется "замыканием" - делегат помнит значение переменной окружения sum, поэтому при любом последующем обращении к нему (когда нажимал в дебаге на разворачивание списка значений data) он вычисляет накопленную сумму, начиная с последнего значения sum, а не с нуля. Подтвердите или поправьте, если я неправ, пожалуйста. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.01.2013, 21:49 |
|
Как вычислить последовательность накопленных средних с помощью встроенных функций?
|
|||
---|---|---|---|
#18+
user7320, замыкание это механизм с помошью которого анонимнаная функция "захватывает" локальную переменную sum. Разный результат работы Select() отражает отложенную природу вычисления содержимого IEnumerable<>. Так что это две разные вещи. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.01.2013, 23:31 |
|
Как вычислить последовательность накопленных средних с помощью встроенных функций?
|
|||
---|---|---|---|
#18+
bazileuser7320, замыкание это механизм с помошью которого анонимнаная функция "захватывает" локальную переменную sum. Разный результат работы Select() отражает отложенную природу вычисления содержимого IEnumerable<>. Так что это две разные вещи. Я выше, ещё в ранних постах жаловался, что эта sum запоминается после каждого прохода функции Select. А проход осуществляется при каждом раскрытии значений коллекции data в дебаггере. А поскольку запомниться эта переменная может только в самом делегате, то я и подумал, что это и есть то самое замыкание. Правильно? ... |
|||
:
Нравится:
Не нравится:
|
|||
09.01.2013, 13:31 |
|
Как вычислить последовательность накопленных средних с помощью встроенных функций?
|
|||
---|---|---|---|
#18+
user7320, она не запоминается, а используется благодаря замыканию. Переменная как была одна так одна и останется независимо от того сколько раз она используется в разных анонимных функциях. Подумай над таким примером: Код: c# 1. 2. 3. 4.
... |
|||
:
Нравится:
Не нравится:
|
|||
09.01.2013, 13:42 |
|
Как вычислить последовательность накопленных средних с помощью встроенных функций?
|
|||
---|---|---|---|
#18+
bazileuser7320, она не запоминается, а используется благодаря замыканию. Переменная как была одна так одна и останется независимо от того сколько раз она используется в разных анонимных функциях. Подумай над таким примером: Код: c# 1. 2. 3. 4.
Ну, здесь в data2 будет использоваться sum, полученная после проходов по source первой функции Select. А где хранится эта sum? Я так понимаю, что делегаты, т. е. анонимные методы, это те же методы и указатели на них, как и их параметры, хранятся в стеке? И ещё вопрос. А вот допустим закончился контекст внешнего окружения делегата, переданного в качестве параметра в Select. Тогда что, переменная sum тоже уничтожилась сборщиком мусора, а в стеке вместе с делегатом осталась КОПИЯ этой переменной в качестве параметра делегата? Или это та же переменная? Другими словами, адрес переменной sum из окружения и переменной sum в делегате одинаков? ... |
|||
:
Нравится:
Не нравится:
|
|||
10.01.2013, 04:12 |
|
|
start [/forum/topic.php?fid=20&gotonew=1&tid=1405385]: |
0ms |
get settings: |
10ms |
get forum list: |
16ms |
check forum access: |
5ms |
check topic access: |
5ms |
track hit: |
62ms |
get topic data: |
11ms |
get first new msg: |
8ms |
get forum data: |
3ms |
get page messages: |
54ms |
get tp. blocked users: |
1ms |
others: | 13ms |
total: | 188ms |
0 / 0 |