Когда структуры являются ответом?

Символ r перед регулярным выражением указывает в вызове search () указывает, что регулярное выражение является исходной строкой. Это позволяет использовать обратную косую черту в регулярном выражении как обычные символы, а не в escape-последовательности символов. Позвольте мне объяснить ...

Прежде чем метод поиска re-модуля обрабатывает переданные ему строки, интерпретатор Python принимает начальный проход по строке. Если в строке присутствуют обратные косые черты, интерпретатор Python должен решить, являются ли они частью escape-последовательности Python (например,\n или \ t) или нет.

Примечание: на данный момент Python не заботится независимо от того, является ли или нет '\' метасимволом регулярного выражения.

Если за «\» следует распознанный escape-символ Python (t, n и т. д.), то обратная косая черта и escape-символ заменяются фактическим Unicode или 8-битным символом. Например, '\ t' будет заменен символом ASCII для вкладки. В противном случае он передается и интерпретируется как символ «\».

Рассмотрим следующее.

>>> s = '\t'
>>> print ("[" + s  + "]")
>>> [       ]           // an actual tab character after preprocessing

>>> s = '\d'
>>> print ("[" + s  + "]")
>>> [\d]                // '\d' after preprocessing

Иногда мы хотим включить в строку последовательность символов, которая включает в себя '\ 'без интерпретации Python как escape-последовательности. Для этого мы убегаем '\' с '\'. Теперь, когда Python видит «\», он заменяет две обратные косые черты одним символом «\».

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing

После того, как интерпретатор Python выполнит проход по обеим строкам, они передаются методу поиска re-модуля , Метод поиска анализирует строку регулярных выражений, чтобы идентифицировать метасимволы регулярного выражения.

Теперь '\' также является специальным метасимволом регулярного выражения и интерпретируется как один, если он не убежит в то время, когда выполняется метод re search ().

Рассмотрим следующий вызов.

>>> match = re.search('a\\t','a\\t')        //Match is None

Здесь совпадение - None. Зачем? Давайте посмотрим на строки после того, как интерпретатор Python сделает свой проход.

String 1: 'a\t'
String 2: 'a\t' 

Итак, почему совпадение равно None? Когда search () интерпретирует String 1, поскольку он является регулярным выражением, обратная косая черта интерпретируется как метасимвол, а не обычный символ. Однако обратная косая черта в String 2 не находится в регулярном выражении и уже обработана интерпретатором Python, поэтому ее интерпретируют как обычный символ.

Таким образом, метод search () ищет «escape -t 'в строке' a \ t ', которые не соответствуют.

Чтобы исправить это, мы можем сказать, что метод search () не интерпретирует' \ 'как метасимвол.

Рассмотрим следующий вызов.

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'

Опять же, посмотрим на строки после того, как интерпретатор Python выполнил свой проход.

String 1: 'a\\t'
String 2: 'a\t'

Теперь, когда метод search () обрабатывает регулярное выражение, он видит, что вторая обратная косая черта сбрасывается первым и не должна считаться метасимволом. Поэтому он интерпретирует строку как «a \ t», которая соответствует строке 2.

Альтернативный способ поиска () считать «\» в качестве символа - поставить r перед регулярным выражением. Это говорит интерпретатору Python, что НЕ препроцессор строки.

Рассмотрим это.

>>> match = re.search(r'a\\t','a\\t')           // match contains 'a\t'

Здесь интерпретатор Python не изменяет первую строку, но обрабатывает вторую строку. Строки, переданные в search (), следующие:

String 1: 'a\\t'
String 2: 'a\t'

Как и в предыдущем примере, поиск интерпретирует «\» как единственный символ «\», а не метасимвол, таким образом, соответствует String 2 .

32
задан JulianR 28 February 2009 в 16:43
поделиться

12 ответов

В основном не делайте их слишком большими, и раздавайте их касательно того, когда Вы будете мочь. Я обнаружил этот тот же самый путь... Путем изменения моего Вектора и классов Ray к структурам.

С большей раздаваемой памятью, это обязано вызвать перегрузку кэша.

6
ответ дан 27 November 2019 в 20:30
поделиться

Можно также превратить структуры в объекты Nullable. Пользовательские классы не будут в состоянии к созданному

как

Nullable<MyCustomClass> xxx = new Nullable<MyCustomClass>

, где со структурой nullable

Nullable<MyCustomStruct> xxx = new Nullable<MyCustomStruct>

, Но Вы будете (очевидно), терять все свои функции наследования

-5
ответ дан 27 November 2019 в 20:30
поделиться

Если структуры являются маленькими, и не слишком многие существуют сразу, это ДОЛЖНО размещать их в стек (как долго, поскольку это - локальная переменная и не член класса), и не на "куче", это означает, что GC не должен быть вызван, и выделение памяти / освобождение должно быть почти мгновенным.

При передаче структуры в качестве параметра для функционирования структура копируется, который не только означает больше выделений/освобождения (от стека, который почти мгновенен, но все еще имеет наверху), но издержки в просто передаче данных между 2 копиями. Если Вы передаете через ссылку, это не, выходят, поскольку Вы просто говорите ее, где считать данные с, вместо того, чтобы копировать ее.

я не на 100% уверен в этом, но я подозреваю, что, возвращая массивы через параметр может также дать Вам повышение скорости, поскольку память на стеке зарезервирована для него и не должна быть скопирована, поскольку стек "раскручен" в конце вызовов функции.

-1
ответ дан 27 November 2019 в 20:30
поделиться

Хотя функциональные возможности аналогичны, структуры обычно более эффективны, чем классы. Вы должны определить структуру, а не класс, , если тип будет работать лучше как тип значения, чем ссылочный тип.

В частности, типы структур должны соответствовать всем этим критериям:

  • Логически представляет одно значение
  • Имеет размер экземпляра менее 16 байтов
  • Не будет изменено после создания
  • Не будет приведено к тип ссылки
2
ответ дан 27 November 2019 в 20:30
поделиться

Мой собственный трассировщик лучей также использует структуру Векторы (хотя и не Лучи), и изменение вектора на класс, похоже, не имеет никакого влияние на производительность. В настоящее время я использую три двойника для вектора, поэтому он может быть больше, чем должен быть. Однако следует отметить одну вещь, и это может быть очевидно, но это было не для меня, а это запуск программы за пределами Visual Studio. Даже если вы установите оптимизированную сборку релиза, вы сможете значительно увеличить скорость, если запустите exe вне VS. Любой бенчмаркинг, который вы делаете, должен учитывать это.

0
ответ дан 27 November 2019 в 20:30
поделиться

Вы представили приложение? Профилирование является единственным верным способом видеть, где фактическая проблема производительности. Существуют операции, которые обычно лучше/хуже на структурах, но если Вы не представляете, Вы просто предположили бы относительно того, какова проблема.

4
ответ дан 27 November 2019 в 20:30
поделиться

Я использую структуры в основном для объектов параметра, возвращая несколько сведений из функции и... ничего иного. Не знайте, "правильно" ли это или "неправильно", но это - то, что я делаю.

0
ответ дан 27 November 2019 в 20:30
поделиться

Я думаю, что ключ находится в этих двух операторах из Вашего сообщения:

Вы создаете миллионы из них

, и

я действительно передаю их методам при необходимости, конечно

Теперь, если Ваша структура не меньше чем или равна 4 байтам в размере (или 8 байтов, если Вы находитесь в 64-разрядной системе), Вы копируете намного больше на каждом вызове метода тогда при простой передаче ссылки на объект.

6
ответ дан 27 November 2019 в 20:30
поделиться

В рекомендациях для того, когда использовать структуру, она говорит, что это не должно быть больше, чем 16 байтов. Ваш Вектор составляет 12 байтов, который является близко к пределу. Луч имеет два Вектора, помещая его в 24 байта, который является ясно по рекомендуемому пределу.

, Когда структура становится больше, чем 16 байтов, она больше не может копироваться эффективно с единственным набором инструкций, вместо этого цикл используется. Так, путем передачи этого "волшебного" предела Вы на самом деле делаете намного больше работы при передаче структуры чем тогда, когда Вы передаете ссылку на объект. Поэтому код быстрее с классами eventhough существует больше служебное при выделении объектов.

Вектор мог все еще быть структурой, но Луч является просто слишком большим для работы хорошо структурой.

11
ответ дан 27 November 2019 в 20:30
поделиться

Что-либо записанное относительно упаковки/распаковывания до дженериков.NET может быть взято с чем-то вроде мелкой частицы соли. Типы универсального набора устранили необходимость упаковки и распаковывания типов значения, которое делает структуры использования в этих ситуациях более ценными.

Что касается Вашего определенного замедления - мы должны были бы, вероятно, видеть некоторый код.

9
ответ дан 27 November 2019 в 20:30
поделиться

Первая вещь, которую я искал бы, состоит в том, чтобы удостовериться, что Вы явно реализовали, Равняется и GetHashCode. При отказе сделать это означает, что реализация во время выполнения каждого из них делает некоторые очень дорогие операции для сравнения двух экземпляров структуры (внутренне, это использует отражение для определения каждого из частных полей и затем проверяет их на равенство, это вызывает существенное количество выделения).

Обычно, хотя, лучшая вещь можно сделать, должен выполнить код при профилировщике и видеть, где медленные части. Это может быть открывающий глаз опыт.

6
ответ дан 27 November 2019 в 20:30
поделиться

Массив структур был бы единственной непрерывной структурой в памяти, в то время как объекты в массиве объектов (экземпляры ссылочных типов) должны быть индивидуально обращены указателем (т.е. ссылка на объект на собравшей "мусор" "куче"). Поэтому при обращении к большому количеству объектов сразу структуры дадут Вам увеличение производительности, так как им нужно меньше косвенности. Кроме того, структуры не могут быть наследованы, который мог бы позволить компилятору делать дополнительную оптимизацию (но это - просто возможность и зависит от компилятора).

Однако структуры имеют очень отличающуюся семантику присвоения и также не могут быть наследованы. Поэтому я обычно избегал бы структур за исключением приведенных причин производительности при необходимости.

<час>

структура

массив значений v закодированный структурой (тип значения) похож на это в памяти:

класс

vvvv

массив значений v закодированный классом (ссылочный тип) похожи на это:

pppp

.. v.. v.. v.v..

, где p являются этим указатели или ссылки, которые указывают на фактические значения v на "куче". Точки указывают на другие объекты, которые могут быть вкраплены на "куче". В случае ссылочных типов необходимо сослаться на v через соответствующий p, в случае типов значения, можно получить значение непосредственно через его смещение в массиве.

26
ответ дан 27 November 2019 в 20:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: