CSHARP_GEPARD Telegram 104
ConcurrentDictionary #собес #память

Коллеги, задачка. Прямо с собеса, с пылу-с-жару. Сколько раз значение будет выведено в консоль?


const string Key = "SomeKey";
var topLevel = new ConcurrentDictionary<string, string>();

for (var i = 1; i < 100; i++) {
var thread = new Thread(Add);
thread.Start(topLevel);
}

static void Add(object? val) {
var dict = (ConcurrentDictionary<string, string>)val!;
dict.GetOrAdd(Key, x => {
lock (Lock.Obj)
{
if (dict.TryGetValue(Key, out var value)) return value;
var res = Guid.NewGuid().ToString();
Console.WriteLine(res);
return res;
}
});
}


Усложняем:
1. Теперь заменим тип значения у ConcurrentDictionary на Guid. Естественно строку var res = Guid.NewGuid().ToString(); нужно исправить как var res = Guid.NewGuid().
2. А теперь изменим тип значения на int.

Как же так? Надо пояснить в чём, собственно, дело. Можно скопировать и воспроизвести у себя. И я настоятельно (!) рекомендую это сделать.

---

С одной стороны, суть происходящего проста: ConcurrentDictionary не гарантирует, что элемент по ключу будет создан один и только один раз. Это делается для исключения проблем, которые могут возникнуть при выполнении неизвестного кода под блокировкой, что верно заметил коллега.

А другой стороны, суть происходящего в сложном сценарии не так проста, но всё ещё, кстати, логична.

Когда мы отпускаем lock, то железке нужно время записать данные в память. И чем бОльший объем данных мы записываем в память, тем это дольше, что подтверждает эмпирический опыт коллеги и дальнейшее развитие рассуждений.

Причём скорость зависит (c) от всего сразу: размера данных, количества процессоров, разрядности процессора и скорости памяти. Например, размер int это 4, а string - 8. И, если повезёт, это, в свою очередь, равно sizeof(IntPtr) или nint (в зависимости от разрядности процессора). Если разрядность позволяет записать данные в память за одну операцию, то это дает другим потокам (ядрам) больше времени посоревноваться на скорость. Если поток всего один - то конкуренции нет.

Мораль всего этого такова: осторожнее на собеседованиях. Нет, мораль другая - если мы пишем асинхронный код, то было бы неплохо протестировать наши результаты не только у себя, но, также, на целевой машине и у того парня. Возможно, наш гениальный код будет работать тут, но не там, а вот там - он вообще всё сломает.
🔥6👍21👏1



tgoop.com/csharp_gepard/104
Create:
Last Update:

ConcurrentDictionary #собес #память

Коллеги, задачка. Прямо с собеса, с пылу-с-жару. Сколько раз значение будет выведено в консоль?


const string Key = "SomeKey";
var topLevel = new ConcurrentDictionary<string, string>();

for (var i = 1; i < 100; i++) {
var thread = new Thread(Add);
thread.Start(topLevel);
}

static void Add(object? val) {
var dict = (ConcurrentDictionary<string, string>)val!;
dict.GetOrAdd(Key, x => {
lock (Lock.Obj)
{
if (dict.TryGetValue(Key, out var value)) return value;
var res = Guid.NewGuid().ToString();
Console.WriteLine(res);
return res;
}
});
}


Усложняем:
1. Теперь заменим тип значения у ConcurrentDictionary на Guid. Естественно строку var res = Guid.NewGuid().ToString(); нужно исправить как var res = Guid.NewGuid().
2. А теперь изменим тип значения на int.

Как же так? Надо пояснить в чём, собственно, дело. Можно скопировать и воспроизвести у себя. И я настоятельно (!) рекомендую это сделать.

---

С одной стороны, суть происходящего проста: ConcurrentDictionary не гарантирует, что элемент по ключу будет создан один и только один раз. Это делается для исключения проблем, которые могут возникнуть при выполнении неизвестного кода под блокировкой, что верно заметил коллега.

А другой стороны, суть происходящего в сложном сценарии не так проста, но всё ещё, кстати, логична.

Когда мы отпускаем lock, то железке нужно время записать данные в память. И чем бОльший объем данных мы записываем в память, тем это дольше, что подтверждает эмпирический опыт коллеги и дальнейшее развитие рассуждений.

Причём скорость зависит (c) от всего сразу: размера данных, количества процессоров, разрядности процессора и скорости памяти. Например, размер int это 4, а string - 8. И, если повезёт, это, в свою очередь, равно sizeof(IntPtr) или nint (в зависимости от разрядности процессора). Если разрядность позволяет записать данные в память за одну операцию, то это дает другим потокам (ядрам) больше времени посоревноваться на скорость. Если поток всего один - то конкуренции нет.

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

BY C# Heppard


Share with your friend now:
tgoop.com/csharp_gepard/104

View MORE
Open in Telegram


Telegram News

Date: |

Just at this time, Bitcoin and the broader crypto market have dropped to new 2022 lows. The Bitcoin price has tanked 10 percent dropping to $20,000. On the other hand, the altcoin space is witnessing even more brutal correction. Bitcoin has dropped nearly 60 percent year-to-date and more than 70 percent since its all-time high in November 2021. Commenting about the court's concerns about the spread of false information related to the elections, Minister Fachin noted Brazil is "facing circumstances that could put Brazil's democracy at risk." During the meeting, the information technology secretary at the TSE, Julio Valente, put forward a list of requests the court believes will disinformation. best-secure-messaging-apps-shutterstock-1892950018.jpg Other crimes that the SUCK Channel incited under Ng’s watch included using corrosive chemicals to make explosives and causing grievous bodily harm with intent. The court also found Ng responsible for calling on people to assist protesters who clashed violently with police at several universities in November 2019. Public channels are public to the internet, regardless of whether or not they are subscribed. A public channel is displayed in search results and has a short address (link).
from us


Telegram C# Heppard
FROM American