Желания нет и вряд ли появится. Но я посмотрю как-нибудь, сколько может занять реализация провайдера. Разработчики Snowflake вряд ли будут сами делать поддержку, а на своем проекте мы пишем запросы руками — их не так много и все они простые.
С кроссплатформенными GUI всё сложно. Кроме Авалонии можно попробовать Xamarin.Forms, Eto.Forms, mono.Xwt, QtSharp.
WPF и WinForms вряд ли когда-нибудь портируют на другие платформы.
Вы смотрите на исходники .NET Framework. Исходники .NET Core вот тут: source.dot.net.
Дело в том, что метод в Enumerable.Range в Core оптимизирован так, что работает в ~10 раз быстрее, чем в Framework и по времени выполнения почти не отличается от ручного заполнения массива через цикл.
Мои тесты:
Код
[Params(15_000)]
public int Size;
[Benchmark]
public int Range()
{
int[] arr = Enumerable.Range(0, Size + 1).ToArray();
return arr[0];
}
[Benchmark]
public int Loop()
{
var arr = new int[Size + 1];
for (var i = 0; i < Size; i++)
arr[i] = i;
return arr[0];
}
Плюс Enumerable.Range выполняется всего один раз в коде автора, так что его влияние на общий результат минимально.
Но в целом вы правы: если бы, скажем, этот метод выполнялся в цикле или размер массива был побольше (500к+) или мы бы взяли Framework вместо Core, тогда да — лучше было бы использовать ручное заполнение.
C# версия из статьи на Core 3.1 у меня отрабатывает за 760 ms (Core i7 7700k).
С небольшими оптимизациями — 560 ms:
Код для BenchmarkDotNet
public class LevensteinDistance
{
[Params(15_000, 20_000)]
public int Size;
private string _s1;
private string _s2;
private string _s3;
[GlobalSetup]
public void Setup()
{
_s1 = new string('a', Size);
_s2 = new string('a', Size);
_s3 = new string('b', Size);
}
[Benchmark(Baseline = true)]
public int Levenstein_Orig()
{
return LevDist_Orig(_s1, _s2) + LevDist_Orig(_s1, _s3);
}
public int LevDist_Orig(string s1, string s2)
{
var ca1 = Encoding.UTF8.GetBytes(s1);
var ca2 = Encoding.UTF8.GetBytes(s2);
return LevDist_Orig(ca1, ca2);
}
public int LevDist_Orig(byte[] s1, byte[] s2)
{
var m = s1.Length;
var n = s2.Length;
// Edge cases.
if (m == 0)
{
return n;
}
else if (n == 0)
{
return m;
}
Int32[] v0 = Enumerable.Range(0, n + 1).ToArray();
var v1 = new Int32[n + 1];
v0.CopyTo(v1, 0);
for (var i = 0; i < m; ++i)
{
v1[0] = i + 1;
for (var j = 0; j < n; ++j)
{
var substCost = (s1[i] == s2[j]) ? v0[j] : (v0[j] + 1);
var delCost = v0[j + 1] + 1;
var insCost = v1[j] + 1;
v1[j + 1] = Math.Min(substCost, delCost);
if (insCost < v1[j + 1])
{
v1[j + 1] = insCost;
}
}
var temp = v0;
v0 = v1;
v1 = temp;
}
return v0[n];
}
[Benchmark]
public int Levenstein_Opt()
{
return LevDist_Opt(_s1, _s2) + LevDist_Opt(_s1, _s3);
}
public int LevDist_Opt(string s1, string s2)
{
if (s1.Length == 0)
{
return s2.Length;
}
else if (s2.Length == 0)
{
return s1.Length;
}
var v0 = Enumerable.Range(0, Size + 1).ToArray();
var v1 = new int[Size + 1];
v0.CopyTo(v1, 0);
for (var i = 0; i < s1.Length; i++)
{
v1[0] = i + 1;
for (var j = 0; j < s2.Length; j++)
{
var substCost = (s1[i] == s2[j]) ? v0[j] : (v0[j] + 1);
var delCost = v0[j + 1] + 1;
var insCost = v1[j] + 1;
v1[j + 1] = Math.Min(Math.Min(substCost, delCost), insCost);
}
(v0, v1) = (v1, v0);
}
return v0[s2.Length];
}
}
Убрал вывод через консоль, преобразование строк в массив байтов, в условиях циклов заменил переменные на s.Length, вычисление минимального из трех через два метода Math.Min.
также value тип не может содержать в себе значение null.
Nullable-типы относятся к value типам и могут принимать значение null.
В принципе, почти весь изложенный материал есть в спецификации и у Рихтера в CLR via C#.
Одна из самых популярных причин для обновления конфигурации (или покупки нового PC) — компьютерные игры.
Они вообще, на мой взгляд, здорово толкают развитие всей индустрии.
Недавно столкнулся с очень интересной ситуацией. Искал объектив через Я.Маркет. Отсортировав по цене результаты выбрал один из первых и перешёл по ссылке на страницу магазина. Цена 32000. На следующий день ищу этот же объектив, только сразу на сайте того магазина. И нахожу его за 35000. Подорожал на 3 тысячи за один день? Хм… Снова пользуюсь поиском Я.Маркета. И что я вижу? Одна из первых ссылок — с ценником 32000 в этом же магазине. Перехожу по ссылке — и правда, на странице магазина указана цена 32000.
В общем, как выяснилось, при переходе из Маркета цена одна, а если искать товар на сайте магазина — уже другая. Дальше я разбираться не стал, просто выбрал другой магазин.
Они уже распространяют эту хрень под видом других программ!
Хотел скачать CoolReader (читалка), поисковик выдал одним из первых адрес coolreader.net
С главной страницы скачал установщик, запустил… И вместо ожидаемой программы получил этот самый Mail.Guard.
Самое противное — во все ярлыки Оперы к строке запуска был добавлен их адрес поисковика, чтобы он открывался при каждом старте браузера.
WPF и WinForms вряд ли когда-нибудь портируют на другие платформы.
— github.com/dotnet/winforms
— github.com/dotnet/wpf
Но пока что без дизайнера в студии, так что с миграцией я бы повременил. Чисто попробовать уже можно, да.
Дело в том, что метод в Enumerable.Range в Core оптимизирован так, что работает в ~10 раз быстрее, чем в Framework и по времени выполнения почти не отличается от ручного заполнения массива через цикл.
Мои тесты:
Плюс Enumerable.Range выполняется всего один раз в коде автора, так что его влияние на общий результат минимально.
Но в целом вы правы: если бы, скажем, этот метод выполнялся в цикле или размер массива был побольше (500к+) или мы бы взяли Framework вместо Core, тогда да — лучше было бы использовать ручное заполнение.
С небольшими оптимизациями — 560 ms:
Убрал вывод через консоль, преобразование строк в массив байтов, в условиях циклов заменил переменные на s.Length, вычисление минимального из трех через два метода Math.Min.
Nullable-типы относятся к value типам и могут принимать значение null.
В принципе, почти весь изложенный материал есть в спецификации и у Рихтера в CLR via C#.
Адское сглаживание шрифтов лечится включением opera://flags/#disable-direct-write
(Opera 12 x64, Core i7, 16 Gb, загрузка ядра 100%, все вкладки ощутимо притормаживают)
Они вообще, на мой взгляд, здорово толкают развитие всей индустрии.
В общем, как выяснилось, при переходе из Маркета цена одна, а если искать товар на сайте магазина — уже другая. Дальше я разбираться не стал, просто выбрал другой магазин.
До сих пор поддерживаются разработчиком.
Для Fallout 1: falloutmods.wikia.com/wiki/Fallout1_Resolution_Patch
Для Fallout 2: falloutmods.wikia.com/wiki/Fallout2_High_Resolution_Patch
Хотел скачать CoolReader (читалка), поисковик выдал одним из первых адрес coolreader.net
С главной страницы скачал установщик, запустил… И вместо ожидаемой программы получил этот самый Mail.Guard.
Самое противное — во все ярлыки Оперы к строке запуска был добавлен их адрес поисковика, чтобы он открывался при каждом старте браузера.