И если вы пришли сюда для поиска двух диапазонов столбцов и объединения их друг с другом (например, я), вы можете сделать что-то вроде
op = df[list(df.columns[0:899]) + list(df.columns[3593:])]
print op
. Это создаст новый DataFrame с первым 900 столбцами и ( все) столбцы> 3593 (при условии, что в вашем наборе данных имеется около 4000 столбцов).
Во-первых, единственный способ ответить на вопросы о производительности - это попробовать в обоих направлениях и проверить результаты в реальных условиях.
Тем не менее, другие ответы, которые говорят, что «компилятор» не делает эту оптимизацию, потому что свойство может иметь побочные эффекты как правильные, так и неправильные. Проблема с вопросом (помимо фундаментальной проблемы, на которую просто невозможно ответить без фактической попытки и измерения результата) заключается в том, что «компилятор» на самом деле является двумя компиляторами: компилятор C #, который компилируется в MSIL и JIT-компилятор , который компилирует IL для машинного кода.
Компилятор C # никогда не делает такого рода оптимизацию; как отмечалось, для этого потребуется, чтобы компилятор подключался к вызываемому коду и проверял, что результат, который он вычисляет, не изменяется в течение всего срока действия кода вызываемого абонента. Компилятор C # этого не делает.
Компилятор JIT может. Нет причин, почему это не могло. Здесь есть весь код. Вполне возможно встроить свойство getter, и если джиттер определяет, что встроенное свойство getter возвращает значение, которое может быть кэшировано в регистре и повторно использовано, тогда оно имеет на это право. (Если вы этого не хотите, потому что значение может быть изменено в другом потоке, тогда у вас уже есть ошибка состояния гонки, исправьте ошибку, прежде чем беспокоиться о производительности.)
Действительно ли джиттер делает встроенную функцию fetch и затем регистрирует значение, я понятия не имею. Я почти ничего не знаю о дрожании. Но это разрешено делать, если сочтет нужным. Если вам интересно, делает оно это или нет, вы можете (1) спросить кого-то, кто находится в команде, которая написала джиттер, или (2) проверить jitted-код в отладчике.
И наконец, позвольте мне воспользоваться этой возможностью, чтобы отметить, что вычисления результатов один раз, сохранение результата и повторное использование его - это не всегда оптимизация . Это удивительно сложный вопрос. Оптимизировать все для оптимизации:
Короче говоря, вы не можете знать, записывать ли код для кэширования результата, а не пересчитывать его на самом деле (1) быстрее или (2) лучше выполнять , Лучшая производительность не всегда означает ускорение выполнения конкретной процедуры. Лучшая производительность - это выяснить, какие ресурсы важны для пользователя: время выполнения, память, рабочий набор, время запуска и т. д. - и оптимизация для этих вещей. Вы не можете этого сделать без (1) беседы с вашими клиентами, чтобы узнать, что им небезразлично, и (2) фактически измерить, чтобы увидеть, имеют ли ваши изменения измеримый эффект в нужном направлении.
Если criteria
- тип класса, я сомневаюсь, что он будет оптимизирован, потому что другой поток всегда может изменить это значение в то же время. Для struct
s я не уверен, но мое чувство кишки состоит в том, что он не будет оптимизирован, но я думаю, что это не повлияет на производительность в этом случае.
почему бы не протестировать его?
просто настроить 2 консольных приложения заставляют его смотреть 10 миллионов раз и сравнивать результаты ... не забудьте запустить их как правильно выпущенные приложения, которые были установлены правильно, или же вы не может гарантировать, что вы не просто запускаете msil.
На самом деле вы, вероятно, получите около 5 ответов, в которых говорится: «Не стоит беспокоиться об оптимизации». они явно не записывают подпрограммы, которые должны быть как можно быстрее, прежде чем читать (например, игры).
Если этот фрагмент кода является частью цикла, который выполняется миллиардами раз, то эта оптимизация может быть стоит. Например, максимальные результаты могут быть переопределенным методом, поэтому вам может потребоваться обсудить вызовы виртуальных методов.
На самом деле ТОЛЬКО способ ответить на любой из этих вопросов - это выяснить это это фрагмент кода, который будет полезен при оптимизации. Затем вам нужно знать те вещи, которые увеличивают время выполнения. На самом деле мы, простые смертные, не можем сделать это априори, поэтому просто попробуйте 2-3 разных версии кода, а затем протестируйте их.
Если MaxResults
является свойством then no, он не будет его оптимизировать, потому что геттер может иметь сложную логику, например:
private int _maxResults;
public int MaxReuslts {
get { return _maxResults++; }
set { _maxResults = value; }
}
Посмотрите, как поведение изменится, если оно будет в строке ваш код?
Если нет никакой логики ... любой метод, который вы написали, в порядке, это очень маленькая разница и все о том, насколько читаемо это вам (или вашей команде) ... вы один смотрел на него.
Ваши два примера кода гарантируют, что они будут иметь одинаковый результат в однопоточных средах, которые .Net не являются, и если MaxResults
является полем (а не свойством). Компилятор не может предположить, если вы не используете функции синхронизации, что criteria.MaxResults
не изменится в течение вашего цикла. Если это свойство, он не может предположить, что использование свойства не имеет побочных эффектов.
Эрик Липперт совершенно правильно указывает, что он сильно зависит от того, что вы подразумеваете под «компилятором». Компилятор C # -> IL? Или компилятор IL -> машинного кода (JIT)? И он прав, чтобы указать, что JIT вполне может оптимизировать свойство getter, так как он имеет всю информацию (тогда как компилятор C # -> IL не обязательно). Это не изменит ситуацию с несколькими потоками, но, тем не менее, это хорошая точка.
Он будет вызываться и оцениваться каждый раз. Компилятор не может определить, является ли метод (или геттер) детерминированным и чистым (без побочных эффектов).
Обратите внимание, что фактическая оценка свойства может быть встроена компилятором JIT, что делает его эффективным как быстро как простое поле.
Хорошая практика - сделать оценку свойств недорогой. Если вы выполняете тяжелые вычисления в getter, подумайте о том, чтобы кешировать результат вручную или изменить его на метод.