Pull to refresh

Comments 19

Рискну дать несколько советов:
1. Правило удаление контракта или его минимизации я бы выкинул сразу. Стоит только появиться специфичной реализации, которой нужен, например, (cnn as MySpecificConnection)..., то сразу слетает сигнатура со строкой, а за сигнатурами могут полететь и контракты. Руководствоваться надо не правилом «передам только то, что нужно сейчас», надо передавать то, что нужно по смыслу. Если это соединение с базой данных, то должно быть соединение с базой данных, а не строка.
2. Правило «Уменьшите использование рефлексии» я бы заменил на «увеличьте использование эмиссии» в частности, да и кэширования в целом. Обычно мы используем рефлексию не для сложения 2+2, а там где без нее не обойтись, и практически в любом примере оптимизации рефлексии мы, как правило, не уменьшаем ее использование, а направляем в другое русло, в ту же кодогенерацию. Кэширование вообще приводит порою к увеличению производительности на порядки.
3. Если выковыривать проценты, то надо было сразу избавиться от .FieldCount в циклах, а считать его один раз за пределами цикла. foreach вообще выкинуть,
В принципе немного, но для 5 параметров мы будем иметь 15 строк. Время для StringBuilder? Нет, пожалуй нет.
Еще какое время. Главное аллокацию грамотную провести.

А в целом интересная тема, спасибо.
В чём риск?)
1. Если появляется специфичная реализация, которую не устраивает существует контракт может быть время добавить специфичный новый контракт? На мой взгляд минимизация ведёт к более очевидному и надёжному коду;
2. Согласен, мысль вы поняли верно, а я не совсем верно передал её в заголовке;
3. FieldCount не считается, это просто длина внутреннего массива.
Пожалуйста.
1. Если ошибки одного контракта затыкать другим, то получится невкусный спагетти-код))
3. Во-первых, там далеко не всегда просто «длина внутреннего массива» (посмотрите рефлектором на FieldCount в OleDbDataReader или в OdbcDataReader в качестве примера), а во-вторых, вызов метода get_FieldCount и обращение к значению в стеке — это не одно и то же. А помноженное на длину цикла это много раз не одно и то же ))
1. Получится COM? Мне лично проще наращивать функционал исходя из минимального контракта, чем из теоретически покрывающего все случаи;
2. Про OleDbDataReader и OdbcDataReader полезная информация, но я основывался на том, что Dapper замена Linq-To-Sql, а он использует SqlDataReader. Насчёт get_FieldCount и значения на стеке, как-то об этом не подумал, спасибо.
Когда я вырасту — я буду писать монолитные C++ Web приложения.
Очень часто конкатенацию строк лучше заменять вызовом string.Format, при слиянии нескольких строк разница минимальна (пруф), а плюсы очевидны:
1) Разделение локализируемой и нелокализируемой части сообщение
2) Отделение патерна от вставляемых данных
Согласен, но в данном случае string.Format не применим, т.к. число параметров варьируется. Кстати, внутри string.Format тот же StringBuilder.
Я же писал, что string.Format быстрее не будет. Вопрос исключительно в удобстве пользования и внесения изменений.
Я про скорость тоже ничего не говорил. Солидарен — вопрос удобства.
Кстати, string.Format использует StringBuilder
«Ярким примером такого предсказания является замена массива на список, когда точно известно количество элементов.»

«Другая существенная причина, что операция присвоения по индексу в массиве работает намного быстрее вызова метода Add для списка.»

ошибка перевода ??
Так вроде топик этот — не перевод!
Как же код на Java похож то :) Сначала думал что на нем все и написано пока до IList не добрался.
«foo» + str + «bar» транслируется в вызов String.Concat(), который быстрее чем StringBuilder. Операцию конкатенации нельзя юзать в циклах, в случае же конкатенации строк через плюсик это быстрее чем String.Format() и StringBuilder.

К тому же если есть возможность получить массив строк и сунуть в String.Concat — лучше так и сделать, чем юзать StringBuilder.

Объяснение простое — String.Concat может сразу выделить нужного размера буфер под строку, тогда как StringBuilder-у иногда приходится ресайзить буффер, для чего требуется копирование. А String.Format еще и парсить что-то там должен.

Например вот тестик накидал: pastebin.com/LZuYG1XL
Результат тестика:
Просто через "+": 370 ms
StringBuilder: 609 ms
String.Format: 920 ms

На любую точность и полноценность не претендую, конечно. Но там и по логике получается что конкатенация должна быть быстрее всего.
Спасибо, со String.Concat встречаюсь настолько редко, что даже забыл о его существовании. Действительно, если посмотреть через Reflector он выигрывает благодаря unsafe коду. В защиту StringBuilder могу сказать, что если есть заранее массив строк, то никто не мешает реализовать нехитрый подсчёт длины конечной строки, как в реализации String.Concat, и сообщить его StringBuilder. Думаю результаты будут по-лучше)
Попробовал. StringBuilder с заданным буфером (чтобы все влезало и буфер не ресайзился) работает также как String.Concat на моем примере. Что ожидаемо.
до кучи надо ещё все аргументы к string явно привести (если таковыми не являются), дабы вызывался String.Concat(string, string), а не String.Concat(object, object) :-)
Sign up to leave a comment.

Articles