Обновить
58

Пользователь

51
Подписчики
Отправить сообщение
Для проведения дополнительных тестов открыты все исходные коды. Можно модифицировать их по своему усмотрению и проверять различные интересующие сценарии.

Так что любой товарищ, участвующий в споре или наблюдающий за ним со стороны, может их провести.
Здорово, а я вот лет 7 пользовался дженериками и только на седьмом году чётко понял, что кэшировать переменную в дженерик-методе удобно через статический дженерик класс.

class Cache<T>
{
    public object Instance { get; }
}

static void AnyMethod<T>()
{
    var anyInstance = Cache<T>.Value ?? 
    Cache<T>.Value = ReadOrCreate<T>();
}

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

Возможно, вы уже ушли далеко вперёд в своём профессиональном развитии и для вас все эти замеры выглядят бессмысленно, но со скромных высот моих познаний смысл в них всё же есть.
Извините, конечно, но в дженерик случае через статических класс — это не настолько очевидно, как в обычном. Вы сами-то применяли осознанно такое решение раньше? А если применяли, то на каком году программирования дошли?

… и о чем же?
Оставляю на ваш суд.

Про чайник теперь услышал.
Но у меня не получилось воспроизвести ситуацию с недоинициализацией…

using System;
using System.Threading;
using static System.Console;

namespace Ace.Base.Console
{
	class MyClass
	{
		public static MyClass Instance;

		private MyClass() => Thread.Sleep(5000);

		public static void AsyncInit() => new Thread(() =>
		{
			WriteLine("Started");
			Instance = new MyClass();
		}).Start();
	}

	static class Program
	{

		static void Main(string[] args)
		{
			try
			{
				MyClass.AsyncInit();
				Thread.Sleep(1000);
				WriteLine("Ready");
				WriteLine(MyClass.Instance?.ToString() ?? "<null>");
			}
			catch (Exception e)
			{
				WriteLine(e);
				ReadKey(true);
			}
		}
	}
}
Серьёзно. Это просто, но не очевидно.

Замеры производительности на различных бенчмарках о многом говорят. И если вы считаете, что это рандомные значения, не несущие за собой смысла, то, пожалуйста, факты в студию, разрушьте мою иллюзию и раскроте глаза тем, кто в неё тоже начал верить.
Спасибо, интересный пример, он очень напоминает передачу ссылки вовне из конструктора.
class Tester
{
  BoxedInt2 _box = null;
  public void Set() {
    _box = new BoxedInt2();
  }
  public void Print() {
    var b = _box;
    if (b != null) b.PrintValue();
  }
}

По идее, можно исправить так (если компилятор не соптимизирует)
class Tester
{
  BoxedInt2 _box = null;
  public void Set() {
    var tmp = new BoxedInt2();
    _box = tmp;
  }
  public void Print() {
    var b = _box;
    if (b != null) b.PrintValue();
  }
}

Поскольку вызов конструктора — блокирующая операция.
Я в комментариях признал, что со словарём у меня ненадёжный код и даже внёс соответствующее примечание в публикацию.
Какой смысл в результатах (неправильно проведенного эксперимента) без анализа?
Смысл такой — есть способы ускорения множественных рефлексивных вызовов на основе кэширования результатов, они представлены в статье, и если вы на практике столкнётесь с подобными сценариями, то сразу будете знать куда копать в целях оптимизации.

Кстати, а как же вы делаете выводы (которые в вашей статье есть) без анализа? Просто «что придумывалось»?
Выводы не выходят за рамки ответа на ваш предыдущий вопрос «в чём смысл?».

Ну то есть вы вывалили нам какие-то результаты, полученные неизвестно из чего, и даже не знаете, что они означают. Круто.
Раз вы так уверены в моём невежестве, то могли бы сами и пояснить, что они означают…
В этой статье я не занимаюсь анализом, а всего лишь, как сказано ранее, выдвигаю гипотезу, провожу эксперименты и делюсь результатами — в этом моя цель.

И одна из причин, почему не углубляюсь в анализ, это те дикие дебри, которые лежат за полученными данными, почему они именно такие…

И да, в наработках много экспериментальных идей, которые со временем могут выбраковываться из-за их несостоятельности, это вполне нормальный процесс. Есть и такие, что остаются.
С удовольствием ознакомлюсь с результатами, если вы этим займётесь и поделитесь с остальными. :)
Скажу прямо — если бы кто-то мне платил за то время и силы, что я трачу на статьи, то можно было бы говорить о разжёвывании материала, подробном анализе и детальном рассмотрении всех возможных аспектов.

Сейчас я делаю это as is — указываю на ключевые моменты и идеи, предоставляю примеры, а читатель уже сам решит, что и как ему с этим делать. Я ничего не продаю и не рекламирую, если и публикую ссылки на код, то лишь делюсь личными наработками с другими людьми, и да, иногда кто-то находит там для себя что-то интересное.
Судя по количеству добавлений публикации в закладки, кто-то всё же считает информацию пусть даже потенциально, но полезной.
А другую половину можно.
Ну да, а публикации на хабре они недостойны, дадада.
Достойны, но вы ж должны понимать, что статьи я пишу лишь в своё свободное время for free. Подготовка материалов даже к этой публикации потребовала уйму времени и сил. Да и пишу в основном о том, с чем сам сталкиваюсь на практике. Нужно или не нужно, люди сами уже для себя решат.

На вопрос почему разные CLR генерируют отличающийся код, исчерпывающего ответа не нашёл и в оригинальной дискуссии его тоже не оставили.
Вы сравниваете решение, которое корректно работает всегда, с решением, которое работает иногда, и никак это не оговариваете. Некрасиво.
Данная некорректность обнаружилась уже в ходе обсуждения, и я сразу сделал честное примечание в тексте статьи, что лучше использовать более надёжное решение в плане потокобезопасности.

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

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

Здесь вообще разговор для отельной статьи, так что при желании можете сами углубиться в этот вопрос, а потом поделиться результатами с остальными.
С чего вы взяли? Может, у кого-то однопоточное приложение и ему вполне хватит такого словаря.
Извините, но за детализацией отправлю вас к публикации, где чётко прописаны все исследуемые сценарии.
Дело в том, что часть тестов производительности проведена на обычном словаре, поэтому я не хочу сейчас менять имплементацию и, соответственно, результаты тестов.

Всё предоставлено как есть, каждый сам может внести требуемые правки в реализацию при необходимости и проверить производительность.
Что-то этой проверки не видно в посте.
Вы же мне помогали в комментариях совместно с другими людьми проверять некоторые мои допущения о словаре и блокировках. Основа поста — идеи для реализации TypeOf и RipeType, а моя имплементация вполне может иметь недостатки, и я очень рад, что мне на них указали.

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

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность