Comments 19
Рискну дать несколько советов:
1. Правило удаление контракта или его минимизации я бы выкинул сразу. Стоит только появиться специфичной реализации, которой нужен, например, (cnn as MySpecificConnection)..., то сразу слетает сигнатура со строкой, а за сигнатурами могут полететь и контракты. Руководствоваться надо не правилом «передам только то, что нужно сейчас», надо передавать то, что нужно по смыслу. Если это соединение с базой данных, то должно быть соединение с базой данных, а не строка.
2. Правило «Уменьшите использование рефлексии» я бы заменил на «увеличьте использование эмиссии» в частности, да и кэширования в целом. Обычно мы используем рефлексию не для сложения 2+2, а там где без нее не обойтись, и практически в любом примере оптимизации рефлексии мы, как правило, не уменьшаем ее использование, а направляем в другое русло, в ту же кодогенерацию. Кэширование вообще приводит порою к увеличению производительности на порядки.
3. Если выковыривать проценты, то надо было сразу избавиться от .FieldCount в циклах, а считать его один раз за пределами цикла. foreach вообще выкинуть,
1. Правило удаление контракта или его минимизации я бы выкинул сразу. Стоит только появиться специфичной реализации, которой нужен, например, (cnn as MySpecificConnection)..., то сразу слетает сигнатура со строкой, а за сигнатурами могут полететь и контракты. Руководствоваться надо не правилом «передам только то, что нужно сейчас», надо передавать то, что нужно по смыслу. Если это соединение с базой данных, то должно быть соединение с базой данных, а не строка.
2. Правило «Уменьшите использование рефлексии» я бы заменил на «увеличьте использование эмиссии» в частности, да и кэширования в целом. Обычно мы используем рефлексию не для сложения 2+2, а там где без нее не обойтись, и практически в любом примере оптимизации рефлексии мы, как правило, не уменьшаем ее использование, а направляем в другое русло, в ту же кодогенерацию. Кэширование вообще приводит порою к увеличению производительности на порядки.
3. Если выковыривать проценты, то надо было сразу избавиться от .FieldCount в циклах, а считать его один раз за пределами цикла. foreach вообще выкинуть,
В принципе немного, но для 5 параметров мы будем иметь 15 строк. Время для StringBuilder? Нет, пожалуй нет.Еще какое время. Главное аллокацию грамотную провести.
А в целом интересная тема, спасибо.
+2
В чём риск?)
1. Если появляется специфичная реализация, которую не устраивает существует контракт может быть время добавить специфичный новый контракт? На мой взгляд минимизация ведёт к более очевидному и надёжному коду;
2. Согласен, мысль вы поняли верно, а я не совсем верно передал её в заголовке;
3. FieldCount не считается, это просто длина внутреннего массива.
Пожалуйста.
1. Если появляется специфичная реализация, которую не устраивает существует контракт может быть время добавить специфичный новый контракт? На мой взгляд минимизация ведёт к более очевидному и надёжному коду;
2. Согласен, мысль вы поняли верно, а я не совсем верно передал её в заголовке;
3. FieldCount не считается, это просто длина внутреннего массива.
Пожалуйста.
0
1. Если ошибки одного контракта затыкать другим, то получится невкусный спагетти-код))
3. Во-первых, там далеко не всегда просто «длина внутреннего массива» (посмотрите рефлектором на FieldCount в OleDbDataReader или в OdbcDataReader в качестве примера), а во-вторых, вызов метода get_FieldCount и обращение к значению в стеке — это не одно и то же. А помноженное на длину цикла это много раз не одно и то же ))
3. Во-первых, там далеко не всегда просто «длина внутреннего массива» (посмотрите рефлектором на FieldCount в OleDbDataReader или в OdbcDataReader в качестве примера), а во-вторых, вызов метода get_FieldCount и обращение к значению в стеке — это не одно и то же. А помноженное на длину цикла это много раз не одно и то же ))
0
1. Получится COM? Мне лично проще наращивать функционал исходя из минимального контракта, чем из теоретически покрывающего все случаи;
2. Про OleDbDataReader и OdbcDataReader полезная информация, но я основывался на том, что Dapper замена Linq-To-Sql, а он использует SqlDataReader. Насчёт get_FieldCount и значения на стеке, как-то об этом не подумал, спасибо.
2. Про OleDbDataReader и OdbcDataReader полезная информация, но я основывался на том, что Dapper замена Linq-To-Sql, а он использует SqlDataReader. Насчёт get_FieldCount и значения на стеке, как-то об этом не подумал, спасибо.
0
Когда я вырасту — я буду писать монолитные C++ Web приложения.
+5
«Ярким примером такого предсказания является замена массива на список, когда точно известно количество элементов.»
…
«Другая существенная причина, что операция присвоения по индексу в массиве работает намного быстрее вызова метода Add для списка.»
ошибка перевода ??
…
«Другая существенная причина, что операция присвоения по индексу в массиве работает намного быстрее вызова метода Add для списка.»
ошибка перевода ??
+1
Как же код на Java похож то :) Сначала думал что на нем все и написано пока до IList не добрался.
0
«foo» + str + «bar» транслируется в вызов String.Concat(), который быстрее чем StringBuilder. Операцию конкатенации нельзя юзать в циклах, в случае же конкатенации строк через плюсик это быстрее чем String.Format() и StringBuilder.
К тому же если есть возможность получить массив строк и сунуть в String.Concat — лучше так и сделать, чем юзать StringBuilder.
Объяснение простое — String.Concat может сразу выделить нужного размера буфер под строку, тогда как StringBuilder-у иногда приходится ресайзить буффер, для чего требуется копирование. А String.Format еще и парсить что-то там должен.
Например вот тестик накидал: pastebin.com/LZuYG1XL
К тому же если есть возможность получить массив строк и сунуть в String.Concat — лучше так и сделать, чем юзать StringBuilder.
Объяснение простое — String.Concat может сразу выделить нужного размера буфер под строку, тогда как StringBuilder-у иногда приходится ресайзить буффер, для чего требуется копирование. А String.Format еще и парсить что-то там должен.
Например вот тестик накидал: pastebin.com/LZuYG1XL
+4
Результат тестика:
Просто через "+": 370 ms
StringBuilder: 609 ms
String.Format: 920 ms
На любую точность и полноценность не претендую, конечно. Но там и по логике получается что конкатенация должна быть быстрее всего.
Просто через "+": 370 ms
StringBuilder: 609 ms
String.Format: 920 ms
На любую точность и полноценность не претендую, конечно. Но там и по логике получается что конкатенация должна быть быстрее всего.
0
Спасибо, со String.Concat встречаюсь настолько редко, что даже забыл о его существовании. Действительно, если посмотреть через Reflector он выигрывает благодаря unsafe коду. В защиту StringBuilder могу сказать, что если есть заранее массив строк, то никто не мешает реализовать нехитрый подсчёт длины конечной строки, как в реализации String.Concat, и сообщить его StringBuilder. Думаю результаты будут по-лучше)
0
до кучи надо ещё все аргументы к string явно привести (если таковыми не являются), дабы вызывался String.Concat(string, string), а не String.Concat(object, object) :-)
0
Sign up to leave a comment.
Ускоряя Stackoverflow.com