Здравствуйте, samius, Вы писали:
S>Здравствуйте, Хвост, Вы писали:
Х>>Здравствуйте, samius, Вы писали:
S>>>Каждый примитив отзывчив? А зачем при этом перерисовывать остальные 20 тысяч? чтобы было чем занять процессор? Х>>а как ты реализуешь плавный скролл/зум? S>Заморозкой рендеригна на время скролл-а. Но тот GIS был чисто GDI-шным.
ну собственно так почти у всех сделано, хотя у нас нет заморозки даже в GDI режиме, правда и прозрачности нет.
Здравствуйте, Хвост, Вы писали:
MK>>Ну а че, мож какие подробности? Что рисует эти примитивы, как "отзывчивость" реализуется? На каком компе ты этот "полет" наблюдаешь? Х>военная тайна: рендерер — OpenGL (ето если прозрачность нужна, без хардварной акселлерации прозрачность тоже "летает", но так низенько-низенько ), отзывчивость реализуется тем что реально объект, ответственный за отзывчивость создаётся только в момент начального действия пользователя (тыкнул мышкой в примитив/нажал хоткей/выбрал менюшку), а так по сути 99.99% того что видно на екране — просто картинка. Вроде ничего хитрого.
Так я и думал. Чего ж ты теплое с мягким сравниваешь? WPF не конкурент рисованию ручками на уровне "линию туда, кружочек сюда" по части скорости, как и рисование "линию туда, кружочек сюда" не конкурент WPF по части фич, таких как биндинг. Микрософт, кстати, сама не позиционирует WPF как библиотеку для приложений, требующих столь сложной графики. И люди в здравом уме это понимают.
Здравствуйте, Хвост, Вы писали:
Х>тут недостижимого на C# то что отрисовка на акселлераторе занимает меньшую часть времени отрисовки кадра, основное время — трансформация примитивов из одной координатной системы в другую, тут даже такая вещь как проверка индекса на допустимый диапазон при обращению к массиву даёт проседание в 30%, куда здесь C# тулить?
Ой да ладно. Ты пробовал или снова "боксинг"?
Здравствуйте, MxKazan, Вы писали:
MK>Здравствуйте, Хвост, Вы писали:
Х>>тут недостижимого на C# то что отрисовка на акселлераторе занимает меньшую часть времени отрисовки кадра, основное время — трансформация примитивов из одной координатной системы в другую, тут даже такая вещь как проверка индекса на допустимый диапазон при обращению к массиву даёт проседание в 30%, куда здесь C# тулить? MK>Ой да ладно. Ты пробовал или снова "боксинг"?
что да ладно? про индексы ето факт, если ты про C# то ессно не пробовал, потому как не взлетит очевидно.
Здравствуйте, Хвост, Вы писали:
Х>Здравствуйте, samius, Вы писали:
S>>Здравствуйте, Хвост, Вы писали:
Х>>>военная тайна: рендерер — OpenGL S>>Что тут недостижимого для C#? Х>тут недостижимого на C# то что отрисовка на акселлераторе занимает меньшую часть времени отрисовки кадра, основное время — трансформация примитивов из одной координатной системы в другую
Координатная система тоже 25 раз в секунду меняется?
X>тут даже такая вещь как проверка индекса на допустимый диапазон при обращению к массиву даёт проседание в 30%, куда здесь C# тулить?
Да, кудауж тут C#-у. Он даже по массивам не умеет ходить
Здравствуйте, samius, Вы писали:
S>Здравствуйте, Хвост, Вы писали:
Х>>Здравствуйте, samius, Вы писали:
S>>>Здравствуйте, Хвост, Вы писали:
Х>>>>военная тайна: рендерер — OpenGL S>>>Что тут недостижимого для C#? Х>>тут недостижимого на C# то что отрисовка на акселлераторе занимает меньшую часть времени отрисовки кадра, основное время — трансформация примитивов из одной координатной системы в другую S>Координатная система тоже 25 раз в секунду меняется?
не понял что имелось ввиду. Координаты подавляющего большинства примитивов хранятся всегда в неизменном виде, и их при каждом скролле или зуме необходимо пересчитывать в екранные координаты.
Здравствуйте, Хвост, Вы писали:
Х>Здравствуйте, samius, Вы писали:
S>>Координатная система тоже 25 раз в секунду меняется? Х>не понял что имелось ввиду. Координаты подавляющего большинства примитивов хранятся всегда в неизменном виде, и их при каждом скролле или зуме необходимо пересчитывать в екранные координаты.
Вообще OpenGL и сам умеет пересчитывать координаты, правда только афинные и почти афинные преобразования, те что можно описать матрицей.
Знаю, что хранятся другие координаты, например, геодезические. Но, их ведь можно преобразовать единожды при чтении в "почти экранные", т.е. в такие координаты, которые легко преобразуются как GDI так и OpenGL-ем. Естественно, все операции с координатами следует проводит с оригинальными координатами, а "почти экранные" хороши для рендеринга. Тогда преобразование координат (кроме первоначального) полностью ляжет на железо.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, Хвост, Вы писали:
Х>>Здравствуйте, samius, Вы писали:
S>>>Координатная система тоже 25 раз в секунду меняется? Х>>не понял что имелось ввиду. Координаты подавляющего большинства примитивов хранятся всегда в неизменном виде, и их при каждом скролле или зуме необходимо пересчитывать в екранные координаты. S>Вообще OpenGL и сам умеет пересчитывать координаты, правда только афинные и почти афинные преобразования, те что можно описать матрицей. S>Знаю, что хранятся другие координаты, например, геодезические. Но, их ведь можно преобразовать единожды при чтении в "почти экранные", т.е. в такие координаты, которые легко преобразуются как GDI так и OpenGL-ем. Естественно, все операции с координатами следует проводит с оригинальными координатами, а "почти экранные" хороши для рендеринга. Тогда преобразование координат (кроме первоначального) полностью ляжет на железо.
абсолютно верно, но ето к сожалению шило на мыло, потому как видимых елементов на екране на порядок/порядки меньше чем есть на самом деле, а для возможности акселлерации прийдётся их трансформировать все, а не только видимые, в случае с GDI ето просто смертельно. Что немаловажно, постоянные трансформации вносят ошибки, поетому оказалось проще и еффективней реализовать схему которая есть.
Здравствуйте, Хвост, Вы писали:
Х>Здравствуйте, samius, Вы писали:
S>>Знаю, что хранятся другие координаты, например, геодезические. Но, их ведь можно преобразовать единожды при чтении в "почти экранные", т.е. в такие координаты, которые легко преобразуются как GDI так и OpenGL-ем. Естественно, все операции с координатами следует проводит с оригинальными координатами, а "почти экранные" хороши для рендеринга. Тогда преобразование координат (кроме первоначального) полностью ляжет на железо.
Х>абсолютно верно, но ето к сожалению шило на мыло, потому как видимых елементов на екране на порядок/порядки меньше чем есть на самом деле, а для возможности акселлерации прийдётся их трансформировать все, а не только видимые, в случае с GDI ето просто смертельно. Что немаловажно, постоянные трансформации вносят ошибки, поетому оказалось проще и еффективней реализовать схему которая есть.
На самом деле, мы уже выбились из темы и перешли к деталям реализации GIS-ов.
Но я отвечу.
Порядки не важны, т.к. есть набор видимых элементов, который обновляется в зависимости от позиции и масштаба вьюхи. Есть эффективные алгоритмы пространственного индексирования объектов, которыми можно пользоваться для того, чтобы читать только те объекты, которые требуется отображать. Потому ни трансформировать все объекты ни читать их в память для отрисовки не обязательно. Те что прочитаны — трансформируются один раз софтом в промежуточную систему координат, все остальные разы железом.
Постоянные трансформации не могут вносить ошибки если эти трансформации не туда-обратно. Всегда есть правильные (родные координаты объекта) и все остальные, полученые из них. Вся логика типа кадастра работает с родными координатами, либо непосредственно полученными из родных.
А отрисовке — пофик на точность. Там на пиксель набежит больше любой погрешности.
Здравствуйте, samius, Вы писали:
S>На самом деле, мы уже выбились из темы и перешли к деталям реализации GIS-ов.
так ето здорово во флейме и так в основном пустопорожний разговор, так что ето только в плюс. S>Но я отвечу.
S>Порядки не важны, т.к. есть набор видимых элементов, который обновляется в зависимости от позиции и масштаба вьюхи. Есть эффективные алгоритмы пространственного индексирования объектов, которыми можно пользоваться для того, чтобы читать только те объекты, которые требуется отображать. Потому ни трансформировать все объекты ни читать их в память для отрисовки не обязательно. Те что прочитаны — трансформируются один раз софтом в промежуточную систему координат, все остальные разы железом.
но ведь при скролле/зуме, когда во вьюху попадают новые области, необходимо их заново трансформировать в промежуточную форму, поетому с таким же успехом можно трансформировать сразу в екранную.
S>Постоянные трансформации не могут вносить ошибки если эти трансформации не туда-обратно. Всегда есть правильные (родные координаты объекта) и все остальные, полученые из них. Вся логика типа кадастра работает с родными координатами, либо непосредственно полученными из родных. S>А отрисовке — пофик на точность. Там на пиксель набежит больше любой погрешности.
ну собственно я про точность отрисовки и говорил, например последовательный зум-аут/зум ин на одну и ту же величину и мы видим уже не то что в начале, или например такой вау-эффект как перелёт из одной точки в другую (как в гуглёрсе) уже не выглядит как последовательное умножение матрицы трансформации на какую-то статичную другую, т.к. накапливаются ошибки. В принципе все ети неточности несложно обходятся, но дело в том что незачем, т.к. на данный момент все трансформации в софте.
Здравствуйте, Хвост, Вы писали:
Х>Здравствуйте, samius, Вы писали:
S>>Порядки не важны, т.к. есть набор видимых элементов, который обновляется в зависимости от позиции и масштаба вьюхи. Есть эффективные алгоритмы пространственного индексирования объектов, которыми можно пользоваться для того, чтобы читать только те объекты, которые требуется отображать. Потому ни трансформировать все объекты ни читать их в память для отрисовки не обязательно. Те что прочитаны — трансформируются один раз софтом в промежуточную систему координат, все остальные разы железом. Х>но ведь при скролле/зуме, когда во вьюху попадают новые области, необходимо их заново трансформировать в промежуточную форму, поетому с таким же успехом можно трансформировать сразу в екранную.
Зло. Вьюх может быть несколько (+обзорная, например) с разными экранными координатами. При активной работе с зумом или изменением размеров окна перерисовывать объекты требуется часто, потому софтовый пересчет каждый раз из геодезии в экранные дорог. А из геодезии в промежуточные псевдо-экранные можно считать только однажны.
S>>Постоянные трансформации не могут вносить ошибки если эти трансформации не туда-обратно. Всегда есть правильные (родные координаты объекта) и все остальные, полученые из них. Вся логика типа кадастра работает с родными координатами, либо непосредственно полученными из родных. S>>А отрисовке — пофик на точность. Там на пиксель набежит больше любой погрешности. Х>ну собственно я про точность отрисовки и говорил, например последовательный зум-аут/зум ин на одну и ту же величину и мы видим уже не то что в начале
А я говорил, что только промежуточные, а потом манипуляция матрицей. Потому 1000 раз зум-аут/зум-ин не повлияют на координаты. В любом случае координаты объекта при смене вида меняться не должны. Координаты примитива — пожалуйста. Объект неизменен при прорисовке.
X>или например такой вау-эффект как перелёт из одной точки в другую (как в гуглёрсе) уже не выглядит как последовательное умножение матрицы трансформации на какую-то статичную другую, т.к. накапливаются ошибки.
Как или конкретно как в гуглёрсе? AFAIK там рисуются не примитивы во время таких эффектов. Во всяком случае не десятками тысяч.
Но повторить худо-бедно такой пролет на векторных данных можно. Естественно, будет зависеть от обилия данных и способа проекции (либо проекция текстуры, либо плоский рендеринг по спроектированным с шарика на плоскость координатам). С шарика на плоскость тоже можно схалтурить и поручить железу.
X>В принципе все ети неточности несложно обходятся, но дело в том что незачем, т.к. на данный момент все трансформации в софте.
Софтовые трансформации тоже можно сократить введением промежуточной системы координат. Даже на шарике.
Так что запас по производительности есть и значительный. Потому не вижу неподъемных для C# задачь.
Здравствуйте, gandjustas, Вы писали:
G>И что есть в с++ для управления ресурсами? Наверное хорошый пул потоков или "зеленые" треды? А может там есть выделение памяти в хипе за O(1)?
пул потоков обычно нативный, причём здесь С++? зелёные треды очень хороши для серверов, ага))) хип за O(1) ? в С++ можно аллоцировать память в хипе вообще один раз и на всю жизнь, и обеспечить свой микроменеджмент, при етом рефакторинг кода сведётся фактически к find/replace.
Х>>ух-хаха, я вообще не использую shared_ptr, представляешь? удивительно, да? G>И что же ты используешь?
для шареных объектов? ты знаешь, если грамотно реализовывать софт, и продумывать время жизни, то оказывается и не так уж много мест где одним и тем же объектом владеют (именно владеют) сразу несколько других, в подавляющем большинстве случаев есть какой-то холдер объектов, который раздаёт объекты другим, причём время жизни етих других много меньше времени жизни холдера. Всё ето потому что shared_ptr ето недетерминизм, т.е. время жизни объекта не определено, нельзя взглянуть на код и сказать — вот в етом месте объект мёртв. Ето плохо. Довольно редко но всё же такие ситуации возникают, тогда можно взять shared_ptr или лично я использую обёртку вида intrusive_ptr над ручным вызовом mySubsystem->release(object). Но есчё раз — ети ситуации очень редки. 99.9% объектов в хипе у меня живёт в std контейнерах, auto_ptr'ах, пулах и аренах. Шарятся множество объектов разных типов, но вот шарятся с семантикой владения пара-тройка, и то ето не необходимость, а скорее кривость.
G>>>А вообще-то есть статистика. Так вот проблемы с утечками памяти в unmanaged появляют гораздо чаще проблем с производительностью в managed. Х>>есть статистика, что на десктопах пользователей подавляющее большинство приложений — unmanaged, ето на мой взгляд самая лучшая статистика. G>Эта статистика очень слабо связана с техническими аспектами. Обсуждали уже сотню раз.
конечно, ты вот наверное не застал времена былинные, а вот я тебе расскажу, в году едак в 96-м, когда вышла жава, С++ хоронили все кому не лень, в 98-м, когда вышла студия с J++, миллионы мух кинулись на жаву, "С++ устарел, на дворе Pentium II с 32 мб, а жаве и 4 мб с головой, и не надо думать об утечках памяти, тысячах реализаций строк, системной работе с потоками, с гуём, всё межплатформенно, блаблабла.... рай на земле... етц", был и свой сильверлайт, только назывался java applet, так вот, жаве уже второй десяток давно пошёл, а на десктопах её всё как-то не особо, и жаваапплетами интернет не полон, а десктоп полон нативными С++ приложениями, а интернет нативным С++ флешем, хотя вот жава она ведь по-твоему намного лучше с++, верно? задумайся почему всё ето так, пойми и осознай, что производительность — ето ресурс, и будет им во веки веков, и процессор, который быстрее в два раза другого, стоит в 3 раза дороже, и юзер выберет программу которая может выполнять три функции параллельно а не две.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, Хвост, Вы писали:
Х>>Здравствуйте, samius, Вы писали:
S>>>Порядки не важны, т.к. есть набор видимых элементов, который обновляется в зависимости от позиции и масштаба вьюхи. Есть эффективные алгоритмы пространственного индексирования объектов, которыми можно пользоваться для того, чтобы читать только те объекты, которые требуется отображать. Потому ни трансформировать все объекты ни читать их в память для отрисовки не обязательно. Те что прочитаны — трансформируются один раз софтом в промежуточную систему координат, все остальные разы железом. Х>>но ведь при скролле/зуме, когда во вьюху попадают новые области, необходимо их заново трансформировать в промежуточную форму, поетому с таким же успехом можно трансформировать сразу в екранную. S>Зло. Вьюх может быть несколько (+обзорная, например) с разными экранными координатами. При активной работе с зумом или изменением размеров окна перерисовывать объекты требуется часто, потому софтовый пересчет каждый раз из геодезии в экранные дорог. А из геодезии в промежуточные псевдо-экранные можно считать только однажны.
ну ещё раз, их либо пересчитывать в псевдо-екранные нужно при каждом сдвиге/масштабировании карты (ето если у нас есть псевдоекранные координаты только видимой области) либо пересчитать все координаты (т.е. и те что вне зоны видимости) во внеекранные заранее, тогда можно пользовать аксселлерированые преобразования, но ето как я уже писал шило на мыло.
S>>>Постоянные трансформации не могут вносить ошибки если эти трансформации не туда-обратно. Всегда есть правильные (родные координаты объекта) и все остальные, полученые из них. Вся логика типа кадастра работает с родными координатами, либо непосредственно полученными из родных. S>>>А отрисовке — пофик на точность. Там на пиксель набежит больше любой погрешности. Х>>ну собственно я про точность отрисовки и говорил, например последовательный зум-аут/зум ин на одну и ту же величину и мы видим уже не то что в начале S>А я говорил, что только промежуточные, а потом манипуляция матрицей. Потому 1000 раз зум-аут/зум-ин не повлияют на координаты. В любом случае координаты объекта при смене вида меняться не должны. Координаты примитива — пожалуйста. Объект неизменен при прорисовке.
дык объект то и неизменен, вид примитива и меняется, т.к. матрица трансформации при 1000 раз зум-аут/зум-ин накапливает ошибку.
X>>или например такой вау-эффект как перелёт из одной точки в другую (как в гуглёрсе) уже не выглядит как последовательное умножение матрицы трансформации на какую-то статичную другую, т.к. накапливаются ошибки. S>Как или конкретно как в гуглёрсе? AFAIK там рисуются не примитивы во время таких эффектов. Во всяком случае не десятками тысяч.
ну я имею ввиду скорее манеру полёта а не сам внешний вид
S>Но повторить худо-бедно такой пролет на векторных данных можно. Естественно, будет зависеть от обилия данных и способа проекции (либо проекция текстуры, либо плоский рендеринг по спроектированным с шарика на плоскость координатам). С шарика на плоскость тоже можно схалтурить и поручить железу.
да, можно, если учесть неточности железки и соответственно с этим написать алгоритм пролёта.
X>>В принципе все ети неточности несложно обходятся, но дело в том что незачем, т.к. на данный момент все трансформации в софте. S>Софтовые трансформации тоже можно сократить введением промежуточной системы координат. Даже на шарике.
про проблемы с промежуточную систему координат вроде написал
S>Так что запас по производительности есть и значительный. Потому не вижу неподъемных для C# задачь.
В принципе задачу можно реализовать и на C#, но куча визуальных ништяков отомрёт.
Здравствуйте, Хвост, Вы писали:
Х>задумайся почему всё ето так, пойми и осознай, что производительность — ето ресурс, и будет им во веки веков, и процессор, который быстрее в два раза другого, стоит в 3 раза дороже, и юзер выберет программу которая может выполнять три функции параллельно а не две.
Да прям. На тот же Flash и JS (до V8 и подобных) посмотри. Оба тормозиловы жуткие, куда уж там Java до них. И ничо.
Здравствуйте, Геннадий Васильев, Вы писали: ГВ>А замкнуть "по ссылке" их можно? То есть так, чтобы структура "физически" осталась в стеке конструирующей лямбду функции?
Нет, нельзя. А главное — зачем? ГВ>Или только "по значению", то есть — копированием в соответствующий экземпляр класса сконструированной лямбды?
Нет, никакого копирования нет. Т, что выглядит локальными переменными, становится полями структуры. Все обращения в коде метода к этим локальным переменным превращаются в обращения к полям.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Геннадий Васильев, Вы писали: ГВ>>А замкнуть "по ссылке" их можно? То есть так, чтобы структура "физически" осталась в стеке конструирующей лямбду функции? S>Нет, нельзя. А главное — зачем?
Логически — незачем. С точки зрения быстродействия может дать некоторый выигрыш, поскольку данные не будут лишний раз копироваться.
ГВ>>Или только "по значению", то есть — копированием в соответствующий экземпляр класса сконструированной лямбды? S>Нет, никакого копирования нет. Т, что выглядит локальными переменными, становится полями структуры. Все обращения в коде метода к этим локальным переменным превращаются в обращения к полям.
Стоп, тогда я тебя не понял. Значит, физически, данные в структуре, размещённой в стеке и в объекте-лямбде — одни и те же? Или нет? Мы сейчас обсуждаем ситуацию, когда данные представляют собой структуру (не объект). Для упрощения положим, что лямбда не выходит за пределы скопа, где объявлена замыкаемая структура, то есть время жизни лямбда-объекта гарантированно превышает время жизни замыкаемой структуры и компилятору об этом известно.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
ГВ>...то есть время жизни лямбда-объекта гарантированно превышает время жизни замыкаемой структуры и компилятору об этом известно.
Наоборот, разумеется — время жизни лямбды гарантированно меньше времени жизни структуры.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Геннадий Васильев, Вы писали:
ГВ>Стоп, тогда я тебя не понял. Значит, физически, данные в структуре, размещённой в стеке и в объекте-лямбде — одни и те же?
Нет, никакого размещения в стеке не происходит. В зависимости от того, что именно замкнуто в контекст, он превращается либо в набор статических переменных + статический метод-лямбду, либо в объект сгенерированного класса, размещенного в хипе (методом которого опять же является лямбда). ГВ>Или нет? Мы сейчас обсуждаем ситуацию, когда данные представляют собой структуру (не объект).
Я, если честно, не уверен, что именно генерируется — структура либо объект. ГВ>Для упрощения положим, что лямбда не выходит за пределы скопа, где объявлена замыкаемая структура, то есть время жизни лямбда-объекта гарантированно превышает время жизни замыкаемой структуры и компилятору об этом известно.
В шарпе "замыкаемая структура" и "лямбда" неразрывно связаны.
Поэтому у них соответствующее время жизни. Примерно так же эта механика работает в JS, только там — полная динамика, а в шарпе — статическая компиляция и типобезопасность.
Далее, размещать эту фигню в стеке компилятор не будет — escape analysis пока что не реализован. Чтобы
не было недопонимания: escape-analysis компилятор вообще выполнять не может. Кроме примитивных случаев типа "объект вообще нигде не используется после создания". В частности, потому, что ему совершенно неизвестно, чем именно занимается метод myCollection.Where(), в который скормили лямбду — он запросто мог сохранить на нее ссылку в каком-то GC Root, для последующего злостного обращения к ней в надежде на UB.
Известно это становится только JITу, и то не всегда. Поэтому escape analysis, как и inlining, в управляемой среде выполняется рантаймом. К джаве первое уже прикрутили, к дотнету пока — только второе.
К счастью, стоимость размещения в хипе в управляемой среде ненамного выше стоимости размещения в стеке. Для того, чтобы написать программу, в которой будет заметен эффект от того, что лямбда размещена не в стеке, нужно очень-очень постараться. А мы тем временем продолжаем надеяться на то, что за то время, которое тебе потребуется для написания этой программы, к CLR таки прикрутят escape analysis. А в отличие от нативного кода, MSIL всех приложений автоматически выиграет от этого будущего улучшения без явной перекомпиляции и передеплоймента приложений.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>К счастью, стоимость размещения в хипе в управляемой среде ненамного выше стоимости размещения в стеке.
Заметно, если вспомнить foreach по перечислителю-структуре и по перечислителю-классу. Но что-то я не замечал, что бы большинство занимались ручной реализацией перечислителей на структурах. Т.е. в большинстве случаев приемлемо (и лямбда с замыканием на хипе и перечислитель на интерфейсе), а если профайлер скажет что беда, недолго переписать низкоуровневыми средствами критичный кусок.
S>Для того, чтобы написать программу, в которой будет заметен эффект от того, что лямбда размещена не в стеке, нужно очень-очень постараться. А мы тем временем продолжаем надеяться на то, что за то время, которое тебе потребуется для написания этой программы, к CLR таки прикрутят escape analysis. А в отличие от нативного кода, MSIL всех приложений автоматически выиграет от этого будущего улучшения без явной перекомпиляции и передеплоймента приложений.
Да не, можно найти тысячу ситуаций (искувственных и натуральных), где разница в способе размещения замыкания будет заметна. Взять хотя бы тот же расчет координат в GIS-ах. Да, точно! В таких нагруженных случаях пользоваться лямбдой вообще неуместно, потому говорить о разнице между размещением замыкания лямбды на стеке и хипе как-бы неуместно. Боюсь что больше будет заметна разница лямбд на делегатах (в C#) и лямбд на виртуальных функциях (Nemerle и F#).