- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
static string BuildPostData(IDictionary<string, string> d)
{
var s = "";
for (var i = 0; i < d.Count; i++)
{
var item = d.ElementAt(i);
var key = item.Key;
var val = item.Value;
s += String.Format("{0}={1}", key, HttpUtility.UrlEncode(val));
if (i != d.Count - 1)
s += "&";
}
return s;
}
Встретил вот такое.... переписал кодом ниже. Меньше мусора и работает намного быстрее.
static string BuildPostData(IEnumerable<KeyValuePair<s tring, string>> d)
{
return string.Join("&", d.Select(i => string.Format(CultureProvider.Common, "{0}={1}", i.Key, HttpUtility.UrlEncode(i.Value))));
}
Вот например, какую коллекцию кроме словаря aka dictionary<tkey, tvalue> они собираются получать на входе.
Зачем там задана культура, вдь с латиницей же работают люди, для чего энкодинг мне тоже не очень понятно.
Почему строку "&" не вынести в string.format, тогда можно было бы просто создать стрингбилдер и обойтись одним проходом по коллекции.
Чтобы полученную строу параметров не распидорасило от val, в котором есть &, % или другие спецсимволы.
> Почему строку "&" не вынести в string.format
Потому, что после последнего параметра она не нужна.
P.S. Неужели в шарпе изкоробки нет нормального построителя HTTP запросов, который соблюдает все правила составления урлов? Чего-нибудь в духе
Энкодинг только на валью, а не на всю строку.
>>Потому, что после последнего параметра она не нужна.
Это прогблема сделать ее в стрингформате до?
Есть. WebClient, HttpRequest, HttpResponse, тысячи их.
Так он и энкодит только value. Ну я бы еще key, конечно, заэнкодил. А вот всю строку целиком энкодить нельзя (я думаю вы понимаете, почему).
> Это прогблема сделать ее в стрингформате до?
А слева она нахера? Чтобы потом ее потом отрезать сабстрингом?
> Я не знаю тонкостей задачи
По моему, всё вполне очевидно: нужно подготовить тело для POST-запроса.
По коду сужу а не по названию метода.
Цитата: Ага, а параметры в урле передаются что ли?
Цитата: Это прогблема сделать ее в стрингформате до?
Цитата: для чего энкодинг
Ну ладно бы просто незнание, в незнании нет ничего страшного, всегда можно найти\спросить\додумать. Другое дело когда человек не знает, но считает, что он прав. Вот это и можно назвать анскильностью. А код с "&{0}={1}" - некорректной питушней.
А вы можете называть как хотите.
Буду рад увидеть ваш вариант.
Я просто ошибся, чуточку.
Гневные слова не за незнание, отнюдь, а только за стиль подачи этого незнания в духе "я все знаю, а вы все питушки" ;)
Я не знаю тонкостей задачи, но мне кажется топикстартер тупо пользовался подсказками решарпера.
Это прогблема сделать ее в стрингформате до?
Ага, а параметры в урле передаются что ли?
Я ничего не имею против такого тона, когда говорящий им на 146% уверен в своей правоте. Да что тут далеко ходить, я сам так часто пишу ;) Но когда такой стиль речи юзают не зная темы - это не айс. В конце-концов, если не уверен, можно написать "емнип" или "имхо" или "мне кажется".
/thread
Хотя смотря какую.
Вот по этому хотелось бы задачку.
Попробуйте программно запостить сюда http://validator.w3.org/check документ на валидацию.
Отправил парочку, просмотрел тело, параметры в урле, метод - get.
Моя первая ссыль - это url обработчика формы, на который приходит POST
Той же самой причиной, по которой пыхеры пишут ' вместо ". Потому что так работает быстрее. И насрать им, что сам HTTP запрос исполняется на 3-4 порядка медленнее, чем его построение, и стринг билдер тут даст никому не нужный профит в жалкие наносекунды (зато явно снизит читабельность)...
Основная причина такого рода оптимизаций - анскильность (простите за слово из лексикона Царя, но оно мне понравилось), и незнание того, что оптимизировать нужно "горячий" код, а не все подряд.
> одним
Код в студию.
А не исходя из ГК.
Но блин у стринга есть свой джоин.
Облажался номер два. :(
Кстати насчет кодировки, может быть можно было закодировать весь шаблон сразу? Вто так: HttpUtility.UrlEncode("{0}={1}") Так и кей и валью сразу же.
или нельзя?
Но как это относится к шаблону? Строку же можно создать форматом и в самом UrlEncode.
P.S. А если распарсит - то это очень плохой сервер, поощряющий говнокод.
Да тут и по вызову понятно - линк вызывается от коллекции, которую нужно обработать, а не статично
На си хотя бы. Но многие программисты на шарпах, пыхах и прочих высокоуровневых языках, к сожалению, думают, что если они будут делать нанооптимизации типа замены " на ' или сложения двух-трех строк через стрингбилдер, то вся программа по волшебству начнет работать быстрее...
А вообще в VS 12 есть тесты производительности которое сами покажут тебе узкие места программы , но, почему-то, ими никто не пользуется
Ну и еще, наверное, сказывается то, что про профайлер надо еще узнать...
Раз пошла такая тема... Кто откуда черпает знания о шарпике?
Я вот сейчас читаю "C# 4.0 и платформа .NET4 для профессионалов" - отличная книга.
Четверо слепых подошли к слону. Один дотронулся до ноги слона и сказал: «Слон похож на столб». Другой дотронулся до хобота и сказал: «Слон похож на толстую дубину». Третий дотронулся до живота слона и сказал: «Слон похож на огромную бочку». Четвёртый дотронулся до ушей и сказал: «Слон похож на большую корзину». И потом они начали спорить между собой относительно того, каков слон.
Конец!
Это просто шутка. :)
С говнокода :) Мое знакомство с шарпиком, к сожалению, началось и закончилось лет 8 тому назад... С тех пор я им толком и не занимался.
Хотя две - три строки нормальный шарпей запилит в шаблон.
Избавление от мусора это, внезапно, оптимизация. В данном случае - микрооптимизация. Т.к. параметров у запроса всяко не так уж и много, а прилетевший ответ и его парсинг напрягут кучу посильнее, чем этот жалкий килобайт.
Вот, что вы делаете для каждого элемента, больше ничего.
>>решарпер вообще тут ни при чем
Он у меня стоит и тоже подсказывает подписать вместо Dictionary, Ienumerable.
Думал, что джоин к каждому элементу добавит.
Критикуешь - предлагай, предлагаешь - делай
Аффтор, хочешь быстрый код - избавься от string.Format. Простая конкатенация строк намного быстрее.
static string BuildPostData(IEnumerable<KeyValuePair<s tring, string>> d)
{
return string.Join("&", d.Select(i => i.Key + "=" + HttpUtility.UrlEncode(i.Value)));
}
Тесты показали прирост производительности на 33%. Guest - Вам респект.
>> i.Key + "=" + HttpUtility.UrlEncode(i.Value)
Это юмор такой?
Лишние строки может убрать только сборщик мусора.
Чем больше вызовов сборщика мусора, тем больше убытки производительности.
Это написано в CLR via C#, которую вы читали.
Почему вы сейчас от своих слов отказываетесь, увидев, что плюсик сделает ваш миленький код быстрее, непонятно.
Я все еще думаю. Мне еще не доводилось строить в шарпе тело пост запроса в ручную, я всегда просто указывал параметры и отправлял запрос и смотрел что ушло, что пришло.
Плюс там милейшее S+= в цикле, что создает i строк в куче с арифметически прогрессируемым размером.
Join сначала все подстроки сделает, а потом сливает
Насчет формата:
Кроме литерала шаблона, нет не должен.
Думаю там стрингбилдер
StringBuilder result = new StringBuilder();
if (en.Current != null) {
result.Append(en.Current);
}
while (en.MoveNext()) {
result.Append(separator);
if (en.Current != null) {
result.Append(en.Current);
}
}
return result.ToString();
Она же в бинарной куче создаст i стрингов. Если словарь из 3 записей еще ничего. но если из 1000...
static string foo(IDictionary<string, string> d)
{
var s = new StringBuilder();
foreach (var key in d.Keys)
s.Append(key + "=" + HttpUtility.UrlEncode(d[key]) + "&");
return s.Remove(s.Length-1,1).ToString();
}
Ибо делать итератор и условие в цикле лишь для того что бы исключить первый амперсант - богомерзко
facepalm.jpg
Конкатенация никуда не делась...
Закопипастил
Я думаю, парни, вы слабо оптимизировали, надо было сильнее оптимизировать.
В студию код на ассемблере
> head = state == 0 ? key : value; } }
> return result; } }
Лисп головного мозга ;)
> host
Причем тут хост? Тут же query string собирают.
P.S. Что-то мне намекает, что этот "оптимизированный" код будет работать медленнее чем исходный. Да и линкед лист из интов (если он однонаправленный), если я не туплю, сожрет втрое больше памяти чем обычная строка (ссылка на следующий, значение, тип объекта для GC в каждой ноде).
P.P.S. Раз уж черезжопострингобилдер свелосипедили, то стоит и UrlEncode свелосипедить и заинлайнить руками ;)
Будет ли он медленнее - а это вообще важно? При всех остальных показателях. Я так думаю, что код просто замечательный, и вне зависимости от скорости нужно использовать именно его, а не какое-нибудь другое решение.
pastebin, ideone