- 1
- 2
- 3
- 4
- 5
var lst = new List<string>();
foreach (String parameterName in parameters.Keys) // parameters это Dictionary<String, Object>
{
lst.Add(parameterName + ": " + parameters[parameterName].ToString());
}
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
+145
var lst = new List<string>();
foreach (String parameterName in parameters.Keys) // parameters это Dictionary<String, Object>
{
lst.Add(parameterName + ": " + parameters[parameterName].ToString());
}
Долгий вариант перебора словаря: перебор ключей в цикле и на каждой итерации получение по ключу значения из словаря
3_14dar 08.07.2015 19:22 # 0
bormand 08.07.2015 19:24 # 0
3_14dar 08.07.2015 20:39 # 0
Her 09.07.2015 16:29 # +3
vldalx 09.07.2015 16:47 # 0
а если и дальше говорить о производительности, то простое сцепление строк, через + или string.concat работает быстрее чем string.Format
единственный плюс string.Format это читаемость
kegdan 09.07.2015 17:08 # −1
Значит поиск по ключу в хешталице - это медленно, а переливать из одной коллекции в другую - это норма?
vldalx 08.07.2015 20:40 # 0
Вот такой вариант намного эффективнее:
var lst = new List<string>();
foreach (var parameter in parameters)
{
lst.Add(parameter.Key + ": " + parameter.Value.ToString());
}
более того, в первоначальном варианте, скорость доступа по ключу к элементу словаря колеблется от того, какие строки (т.е. что они из себя представляют) используются в качестве ключа.
kegdan 08.07.2015 21:11 # +1
>> Автор этого кода видимо тоже с трудом представляет что это такое.
Куда уж нам, о Великий!
vldalx 08.07.2015 21:20 # 0
kegdan 08.07.2015 21:29 # 0
Правда, что она бывает ло-ка-ри-фми-чис-кая?
vldalx 08.07.2015 21:52 # 0
Жаль, что вы не видите, или не хотите видеть, разницу между двумя кусками кода.
kegdan 08.07.2015 21:54 # 0
Не надо так.
Тут большинство прекрасно понимает что такое сложность и в чем разница между двумя вариантами
vldalx 08.07.2015 22:01 # 0
Извиняюсь перед bormand.
Судя по минусам к коду, когда еще не было никаких комментариев, то не все всё понимают.
kegdan 08.07.2015 22:02 # +3
Добро пожаловать в реальный мир на говнокод
3_14dar 08.07.2015 21:24 # 0
roman-kashitsyn 08.07.2015 22:40 # +1
А вы?
Я лично вижу, что оба вариант работают за O(n), где n - размер словаря. Правда, в топике - амортизированное O(n), а в вашем варианте - гарантированное.
vldalx 08.07.2015 23:18 # 0
Все зависит от количества коллизий при инициализации словаря.
roman-kashitsyn 08.07.2015 23:22 # 0
vldalx 08.07.2015 23:27 # 0
roman-kashitsyn 09.07.2015 09:50 # 0
kegdan 09.07.2015 09:57 # 0
3_14dar 09.07.2015 10:23 # 0
kegdan 09.07.2015 10:41 # 0
ОООО!!!
roman-kashitsyn 09.07.2015 10:47 # 0
3_14dar 09.07.2015 11:43 # 0
roman-kashitsyn 09.07.2015 11:59 # 0
3_14dar 09.07.2015 12:16 # 0
roman-kashitsyn 09.07.2015 12:29 # +1
3_14dar 09.07.2015 13:33 # 0
roman-kashitsyn 09.07.2015 13:51 # 0
Разумеется. Возможность запоминать информацию тебя удивляет?
kegdan 09.07.2015 14:42 # 0
3_14dar 09.07.2015 15:06 # 0
kegdan 09.07.2015 15:39 # 0
3_14dar 09.07.2015 15:05 # 0
kegdan 09.07.2015 13:27 # +2
3_14dar 09.07.2015 07:29 # 0
1024-- 09.07.2015 10:38 # 0
Строить map как вырожденное в список дерево.
3_14dar 09.07.2015 10:39 # 0
1024-- 09.07.2015 10:44 # 0
Или попробовать как-то обмануть HashMap.
roman-kashitsyn 09.07.2015 10:45 # 0
3_14dar 09.07.2015 10:47 # 0
Они стандартные?
>Посмотрев на реализацию хэша в стд-либе и подобрав коллизии?
На чужой машине это с некоторого времени не работает, на своей - но зачем?
roman-kashitsyn 09.07.2015 10:51 # 0
Ключём в словаре может быть любой тип. Эффективноть работы словаря зависит от качества хэш-функции для типа-ключа, который может быть определён пользователем.
В первых версиях jdk была кривая хэш-функция для строк, просматривавшая не всю строку. Из-за этого для некоторых входов (например, доменных имён), было дикое кол-во коллизий.
3_14dar 09.07.2015 11:11 # 0
>foreach (String parameterName in parameters.Keys)
www, перелогинься.
Для строк хешкод стандартный.
3_14dar 09.07.2015 07:28 # 0
bormand 09.07.2015 08:21 # 0
3_14dar 09.07.2015 08:31 # 0
bormand 09.07.2015 08:44 # 0
> где-то сохранены
Флаг в каком-то виде всяко есть (возможно неявный, в виде какого-нибудь null'а). Иначе поиск и вставку не реализовать.
bormand 09.07.2015 08:47 # 0
Вот так в жабе реализован обход мапы.
3_14dar 09.07.2015 08:53 # 0
>openjdk
Ты опять?
Там Entry[], а Entry в добавок хранит ссылку на next. Т.е. в хешмепе параллельно хранится список ключей/значений? Оригинально.
bormand 09.07.2015 08:55 # 0
P.S. По существу вопросы будут?
3_14dar 09.07.2015 08:57 # 0
Опять выходишь на связь? Опять называешь openjdk жавой?
bormand 09.07.2015 08:59 # 0
3_14dar 09.07.2015 09:01 # 0
3_14dar 09.07.2015 09:07 # 0
bormand 09.07.2015 09:09 # 0
3_14dar 09.07.2015 09:11 # 0
bormand 09.07.2015 09:04 # 0
Так они решают проблему с коллизиями хеша - Entry с одинаковым хешем будут лежать в виде связного списка.
3_14dar 09.07.2015 09:08 # 0
bormand 09.07.2015 10:58 # 0
3_14dar 09.07.2015 11:08 # 0
bormand 09.07.2015 11:56 # 0
Ваш кэп.
P.S. Ну по коду же всё видно...
roman-kashitsyn 09.07.2015 12:01 # 0
IDE НЕ ПОДСВЕЧИВАЕТ (tm)
3_14dar 09.07.2015 12:10 # 0
3_14dar 09.07.2015 12:12 # 0
roman-kashitsyn 09.07.2015 12:15 # 0
Иди уже поучи матчасть, не позорься.
3_14dar 09.07.2015 12:16 # 0
bormand 09.07.2015 12:19 # 0
Почитай реализацию get() что ли...
3_14dar 09.07.2015 12:22 # 0
bormand 09.07.2015 12:27 # 0
Для поиска см. выше.
Для итерации - да, пробегаем все слоты. Твоя проблема возникнет только в одном случае - если навставлять миллион элементов и погрохать почти все, причем табличка должна не уметь сжиматься (жабья, как я понимаю, как раз не умеет).
Приведи пример практического сценария, когда это произойдёт.
3_14dar 09.07.2015 12:39 # 0
roman-kashitsyn 09.07.2015 11:04 # 0
3_14dar 09.07.2015 11:09 # 0
roman-kashitsyn 09.07.2015 11:28 # 0
Для этого даже образования не надо, лишь чуточку ума.
Пробегаешь по всему массиву бакетов, в каждом бакете посещаешь список пар ключ-значение. Итератору достаточно хранить указатель на текущий бакет и текущую позицию в массиве бакетов.
Конкурентные модификации хэш-таблицы в жаве запрещаются.
3_14dar 09.07.2015 11:39 # 0
Который с дырками?
roman-kashitsyn 09.07.2015 11:43 # 0
Да, и что, в чём проблема?
Просто скипаешь все дырки, там нулевые укатели. На каждом next() надо бежать до следующего непустого.
3_14dar 09.07.2015 11:44 # 0
В том, что у тебя на мегабайт может быть одно место? И тогда хуй тебе, а не O(количество элементов)
roman-kashitsyn 09.07.2015 11:49 # 0
И что? Хорошая табличка должна расти с увеличением числа записей, чтобы кол-во бакетов было всегда порядка O(n) от n записей. Поэтому в худшем случае вся итерация в сумме будет работать O(n).
Если планируется удалять много записей, нужна табичка, которая шринкается при низком load factor.
3_14dar 09.07.2015 12:15 # 0
Ты понял, что за хуйню ты сморозил? В O сокращается множитель. Нет, ну O(количество записей) то останется, но множитель может быть неприятным.
А вдруг таблицы которые в языках - плохие?
roman-kashitsyn 09.07.2015 12:26 # 0
> множитель может быть неприятным
Ну ты и лалка. Почитай про load factor чтоли.
Специально открыл первую статью на вики - даже там про это написано.
Раз думать тебя так и не научили.
bormand 09.07.2015 12:30 # 0
3_14dar 09.07.2015 12:38 # 0
roman-kashitsyn 09.07.2015 15:18 # 0
В крестах (gcc) unordered_map тоже не шринкается. Шарповый Generic.Dictionary тоже.
Что даёт на O(N) на итерацию, где N - максимальный размеров словаря, наблюдаемый за время его существования. Если предположить, что элементы удаляются не сильно чаще, чем добавляются, то получаем эффективное O(n) с константой порядка 2-4.
Видимо, шринк - настолько редкое требование, что его никто не делает из коробки.
Пистоний словарь вроде как может ресайзиться в меньшую сторону, но в коде удаления элементов я этого не нашёл.
Те, у кого сильно специфический ворклоад, вполне могут позволить себе запилить эвристический шринк, чтобы отвязаться от N.
3_14dar 09.07.2015 15:21 # 0
bormand 09.07.2015 15:44 # 0
roman-kashitsyn 09.07.2015 15:51 # 0
3_14dar 09.07.2015 16:50 # 0
kegdan 09.07.2015 16:55 # 0
Да и кому надо сам напишет
3_14dar 09.07.2015 17:08 # 0
kegdan 09.07.2015 17:09 # −1
Проблемы нет, просто не нужно
3_14dar 09.07.2015 17:38 # −1
kegdan 09.07.2015 18:16 # −1
3_14dar 09.07.2015 18:20 # −1
kegdan 09.07.2015 19:01 # −1
3_14dar 09.07.2015 19:12 # −1
kegdan 09.07.2015 19:40 # 0
3_14dar 09.07.2015 19:53 # 0
kegdan 09.07.2015 19:59 # 0
координаты GPS дай
3_14dar 09.07.2015 21:28 # 0
kegdan 09.07.2015 21:31 # 0
3_14dar 09.07.2015 22:32 # 0
roman-kashitsyn 09.07.2015 23:33 # 0
3_14dar 09.07.2015 23:34 # 0
kegdan 09.07.2015 23:37 # −1
Ум - он скорбь приумножает. Наверное иногда хочется отупеть как сема, вот и несу херню
3_14dar 10.07.2015 00:00 # −1
Vasiliy 09.07.2015 19:02 # −1
>похороним
т.е. Ты настолько пидар, что если kegdan приедет тебя пиздить ты обосрешься выйти один.
3_14dar 09.07.2015 19:12 # −1
3_14dar 09.07.2015 12:37 # −1
roman-kashitsyn 09.07.2015 12:45 # 0
У меня будет, лалка. Мне не составляет никакого труда реализовать хэш-таблицу, которая будет гарантировать O(n) итерацию.
То, что дефолтная жаба делает что-то определённым образом не означает, что что-то невозможно.
Кроме того, жабий HashMap поддерживает keySet() которая позволяет быстро обходить только ключи и лукапить значения по ключу, если уж есть сценарий с массовым удалением.
3_14dar 09.07.2015 13:02 # −1
>позволяет быстро обходить только ключи
И как она это делает? Отдельно хранит ключи?
kegdan 09.07.2015 13:34 # 0
В шарповском словаре помимо бакетов есть тупо линейный список контейнеров, в котором лежит хеш, номер следующего (если есть), ключ и значения. Просто по нему пробегаешь и достаешь что хочешь.
Может я в терминологии путаюсь, но вроде как словарь в шарпе - это и есть хэш-таблица
3_14dar 09.07.2015 15:06 # −1
bormand 09.07.2015 06:37 # 0
Нет, а что это?
> Автор этого кода...
...раньше однозначно писал на js (или perl'е?). Ну просто я не помню других языков, где кроме идиомы из топика ничего не работает.
> намного эффективнее
Ну не так уж намного. В общем-то в типичной прикладнухе разницу и не заметить.
kegdan 09.07.2015 07:38 # 0
Мой суррогатный тестовый код
https://ideone.com/kXelZy
скрины профилировщика ннадо?
3_14dar 09.07.2015 07:52 # −1
Ух ты, сисярп умеет в foreach по словарю?
> for (int i = 0; i < 10000; i++,key += "1")
Ключи в 10k символов - такой типичный случай? Сделай что-нибудь поумнее.
kegdan 09.07.2015 08:09 # −1
bormand в http://www.govnokod.ru/18452#comment292495 написал:
>> В общем-то в типичной прикладнухе разницу и не заметить.
3_14dar в http://www.govnokod.ru/18452#comment292502 написал:
>> Ключи в 10k символов - такой типичный случай?
kegdan в http://www.govnokod.ru/18452#comment292500 написал:
>> Мой суррогатный тестовый код
3_14dar 09.07.2015 08:10 # 0
kegdan 09.07.2015 08:12 # −1
>> Ух ты, сисярп умеет в foreach по словарю?
>> Что значит суррогатный?
3_14dar в http://govnokod.ru/18452#comment292502 написал:
>> Сделай что-нибудь поумнее.
лол
3_14dar 09.07.2015 08:14 # 0
kegdan 09.07.2015 08:17 # −1
3_14dar 09.07.2015 08:18 # 0
Поддельный тестовый код?
Vasiliy 09.07.2015 12:12 # 0
3_14dar 09.07.2015 13:34 # −1
kegdan 09.07.2015 13:46 # 0
3_14dar 09.07.2015 15:07 # 0
Vasiliy 09.07.2015 13:58 # −1
3_14dar 09.07.2015 15:07 # −1
guest 10.07.2015 00:11 # 0
guest 10.07.2015 00:59 # 0
guest 10.07.2015 09:14 # 0
3_14dar 10.07.2015 09:14 # 0
guest 10.07.2015 12:32 # +1
3_14dar 10.07.2015 13:40 # 0
guest 10.07.2015 13:43 # 0
3_14dar 09.07.2015 09:00 # 0
bormand 09.07.2015 08:23 # +1
Напугал ежа голой жопой. Т.е. разница только в константе и всего в 2 раза? Причём при диких ключах в ~5000 символов?
Вот когда этот код будет бутылочным горлышком - можно задуматься о профайлере. А до этого в общем-то похуй.
P.S. Но мне вариант с парами больше нравится из-за наглядности.
P.P.S. Попробуй сделать тест на рост сложности - 1к, 10к, 100к.
kegdan 09.07.2015 09:46 # 0
http://download.hdd.tomsk.ru/preview/waefahjh.jpg
все в миллисекундах
Словарь заполняется вот так