Если не использовать [закрытые] лямбда-выражения

Сначала несколько примеров данных. Это должно быть похоже на то, что вы получаете, когда читаете в своем шейп-файле. Пространственный объект R называется a SpatialPolygonsDataFrame. Он содержит data.frame с ковариатной информацией о ваших полигонах.

library(sp)
Sr1  <-  Polygon(cbind(c(2,4,4,1,2),c(2,3,5,4,2)))
Sr2  <-  Polygon(cbind(c(5,4,2,5),c(2,3,2,2)))
Sr3  <-  Polygon(cbind(c(4,4,5,10,4),c(5,3,2,5,5)))
Sr4  <-  Polygon(cbind(c(5,6,6,5,5),c(4,4,3,3,4)), hole = TRUE)
Srs1  <-  Polygons(list(Sr1), "s1")
Srs2  <-  Polygons(list(Sr2), "s2")
Srs3  <-  Polygons(list(Sr3, Sr4), "s3/4")
SpP  <-  SpatialPolygons(list(Srs1,Srs2,Srs3), 1:3)
Spdf <- SpatialPolygonsDataFrame(SpP, data.frame(name = c("a", "b", "c"), row.names = c("s1", "s2", "s3/4")))

Теперь у вас есть пространственный объект, который вы можете нарисовать:

plot(Spdf)

и взгляните на прикрепленный data.frame вашего пространственного объекта. Здесь вам нужно иметь некоторый идентификатор, который будет соответствовать вашим результатам выборов:

Spdf@data

У вас также есть другой фрейм данных с вашими «результатами выборов» (также с этим идентификатором)

election <- data.frame(name = c("a", "c", "b"), voted = c(0.1, 0.2, 0.3))

[1116 ] Теперь сопоставьте в результатах выборов с вашим пространственным объектом, чтобы вы могли построить его:

Spdf@data$voted <- election$voted[match(Spdf$name, election$name)]

Чтобы нарисовать полигоны с результатом голосования как цвет многоугольника, вам нужна палитра:

[115 ]

Затем просто начертите:

plot(Spdf, col = Spdf@data$colour)

enter image description here

Вы можете представить, что у вас будет более 3 перерывов масштаб, и у вас будет больше полигонов, но это только пример. Удачи!

52
задан Community 23 May 2017 в 01:53
поделиться

7 ответов

Даже при том, что я сфокусируюсь на точке один, я начинаю путем предоставления моих 2 центов по целой проблеме производительности. Если различия не являются большими, или использование интенсивно, обычно я не беспокоюсь о микросекундах, которые при добавлении не составляют видимое различие для пользователя. Я подчеркиваю, что только не забочусь при рассмотрении неинтенсивных вызываемых методов. То, где у меня действительно есть специальные соображения производительности, находится на способе, которым я разрабатываю само приложение. Я забочусь о кэшировании, об использовании потоков, об умных способах назвать методы (выполнить ли несколько вызовов или пытаться выполнить только один вызов), объединить ли соединения или нет, и т.д., и т.д. На самом деле я обычно не фокусируюсь на необработанной производительности, но на scalibility. Я не забочусь, работает ли это лучше крошечной частью наносекунды для отдельного пользователя, но я хочу много иметь способность загрузить систему большими количествами одновременных пользователей без того, чтобы замечать влияние.

Однако здесь идет мое мнение о точке 1. Я люблю анонимные методы. Они дают мне большую гибкость и кодируют элегантность. Другая замечательная особенность об анонимных методах - то, что они позволяют мне непосредственно использовать локальные переменные от метода контейнера (с точки зрения C#, не с точки зрения IL, конечно). Они экономят меня загрузки кода часто. Когда я использую анонимные методы? Evey единственное время часть кода, в котором я нуждаюсь, не необходим в другом месте. Если это используется в двух различных местах, мне не нравится вставка копии как метод повторного использования, таким образом, я буду использовать простого делегата. Так, точно так же, как shoosh ответил, не хорошо иметь дублирование кода. В теории нет никаких различий в производительности, как анонимы являются приемами C#, не материалом IL.

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

public static void DoSomethingMethod(string[] names, Func<string, bool> myExpression)
{
    Console.WriteLine("Lambda used to represent an anonymous method");
    foreach (var item in names)
    {
        if (myExpression(item))
            Console.WriteLine("Found {0}", item);
    }
}

Это получает массив строк и для каждого из них, это будет звонить, метод передал ему. Если тот метод возвратит true, то он скажет "Найденный...". Можно назвать этот метод следующим путем:

string[] names = {"Alice", "Bob", "Charles"};
DoSomethingMethod(names, delegate(string p) { return p == "Alice"; });

, Но, можно также назвать это следующим путем:

DoSomethingMethod(names, p => p == "Alice");

нет никакого различия в IL между обоими, будучи, что тот с помощью Лямбда-выражения намного более читаем. Еще раз нет никакого влияния производительности, поскольку это все приемы компилятора C# (не приемы JIT-компилятора). Так же, как я не чувствовал, что мы злоупотребляем анонимные методы, я не чувствую, что мы злоупотребляем Лямбда-выражения для представления анонимных методов. Конечно, та же логика относится к повторному коду: не делайте лямбд, используйте постоянных делегатов. Существуют другие ограничения, приводящие Вас обратно к анонимным методам или простым делегатам, как или касательно передачи параметров.

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

public static void DoSomethingExpression(string[] names, System.Linq.Expressions.Expression<Func<string, bool>> myExpression)
{
    Console.WriteLine("Lambda used to represent an expression");
    BinaryExpression bExpr = myExpression.Body as BinaryExpression;
    if (bExpr == null)
        return;
    Console.WriteLine("It is a binary expression");
    Console.WriteLine("The node type is {0}", bExpr.NodeType.ToString());
    Console.WriteLine("The left side is {0}", bExpr.Left.NodeType.ToString());
    Console.WriteLine("The right side is {0}", bExpr.Right.NodeType.ToString());
    if (bExpr.Right.NodeType == ExpressionType.Constant)
    {
        ConstantExpression right = (ConstantExpression)bExpr.Right;
        Console.WriteLine("The value of the right side is {0}", right.Value.ToString());
    }
 }

Уведомление немного отличающаяся подпись. Второй параметр получает выражение и не делегата. Способ назвать этот метод был бы:

DoSomethingExpression(names, p => p == "Alice");

, Который является точно тем же как вызовом, который мы выполнили при создании анонимного метода с лямбдой. Различие здесь - то, что мы не создаем анонимный метод, но создаем дерево выражений. Это происходит из-за этих деревьев выражений, что мы можем тогда перевести лямбда-выражения в SQL, который является тем, что Linq 2 SQL делает, например, вместо того, чтобы выполнить материал в механизме для каждого пункта как Где, Выбор, и т.д. Хорошая вещь состоит в том, что синтаксис вызова является тем же, создаете ли Вы анонимный метод или отправляете выражение.

32
ответ дан Dan Atkinson 7 November 2019 в 09:18
поделиться

Дублирование кода.
, Если Вы пишете ту же анонимную функцию несколько раз, это не должно быть то.

16
ответ дан shoosh 7 November 2019 в 09:18
поделиться

Ну, когда мы говорим делегат поединка использование, не должно быть никакого различия между лямбдой и анонимными методами - они - то же, только с другим синтаксисом. И названные методы (используемый в качестве делегатов) также идентичны с точки зрения времени выполнения. Различие, тогда, между использованием делегатов, по сравнению со встроенным кодом - т.е.

list.ForEach(s=>s.Foo());
// vs.
foreach(var s in list) { s.Foo(); }

(где я ожидал бы, что последний будет более быстрым)

И одинаково, если Вы говорите о чем-нибудь другой , чем объекты в оперативной памяти, лямбды являются одним из Ваших самых мощных инструментов с точки зрения поддержания проверки типа (вместо того, чтобы анализировать строки все время).

, Конечно, существуют случаи, когда простое foreach с кодом будет быстрее, чем версия LINQ, поскольку будет, меньше вызывают, чтобы сделать и вызывают, стоит маленького, но измеримого времени. Однако во многих случаях код является просто не узким местом, и более простой код (специально для группировки, и т.д.) стоит намного больше, чем несколько наносекунд.

Примечание также, что в.NET 4.0 существует дополнительно Expression узлы для вещей как циклы, запятые, и т.д. Язык не поддерживает их, но время выполнения делает. Я упоминаю это только для полноты: я, конечно, не говорю, что необходимо использовать конструкцию руководства Expression, где foreach сделал бы!

14
ответ дан Gabe 7 November 2019 в 09:18
поделиться

Я сказал бы, что различия в производительности обычно так небольшие (и в случае циклов, очевидно, при рассмотрении результатов 2-й статьи (btw, у Jon Skeet есть подобная статья здесь )), что Вы почти никогда не должны выбирать решение по одним только причинам производительности, если Вы не пишете часть программного обеспечения, где производительность абсолютно номер один нефункциональное требование, и действительно необходимо сделать micro-optimalizations.

, Когда выбрать что? Я предполагаю, что это зависит от ситуации, но также и человека. Так же, как пример некоторые люди предпочитают Список. Foreach по нормальному циклу foreach. Я лично предпочитаю последнего, поскольку это обычно более читаемо, но кто я должен привести доводы против этого?

6
ответ дан jasper 7 November 2019 в 09:18
поделиться

Эмпирические правила:

  1. Пишут Ваш код, чтобы быть естественным и читаемым.
  2. Избегают дублирований кода (лямбда-выражения могли бы потребовать небольшого дополнительного усердия).
  3. Оптимизируют только, когда существует проблема, и только с данными для поддержки, какова та проблема на самом деле.
4
ответ дан Dustin Campbell 7 November 2019 в 09:18
поделиться

При необходимости в рекурсии не используйте лямбды, , или Вы закончите тем, что были очень отвлечены !

2
ответ дан Daniel Earwicker 7 November 2019 в 09:18
поделиться

Любое время лямбда просто передает свои аргументы непосредственно другой функции. Не создавайте лямбду для функционального приложения.

Пример:

var coll = new ObservableCollection<int>();
myInts.ForEach(x => coll.Add(x))

Более хорошо как:

var coll = new ObservableCollection<int>();
myInts.ForEach(coll.Add)

Основное исключение - то, где сбои вывода типа C# по любой причине (и существует много времен это правда).

4
ответ дан MichaelGG 7 November 2019 в 09:18
поделиться
Другие вопросы по тегам:

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