Bezdepbonusu7Программирование: статьи и ответы

Вопрос

JIT простая оптимизация

Автор вопроса: MayaОтветов: 2

У меня есть следующий метод

void DoSome(){
    if (int.Parse(SomeStringProperty) > 8)
        // do something

    if (int.Parse(SomeStringProperty) < 10)
        // do something
}

Знает ли JIT, что нужно сохранить проанализированное значение, или лучше сделать следующее:

void DoSome(){
    var x = int.Parse(SomeStringProperty);
    if (x > 8)
        // do something

    if (x < 10)
        // do something
}

Здесь я вижу две оптимизации:

  1. JIT автоматически сделает что-то вроде второго примера.
  2. JIT выполняет одну оптимизацию и кэширует результат

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

Короче говоря, когда я пишу приложение на С#, какой из приведенных выше примеров предпочтительнее?

Обновить

Если ответа нет, то почему он отличается от этого:

foreach (var x in MyMethod.GetEnumeration())

здесь не нужно делать:

var lst = MyMethod.GetEnumeration();
foreach (var x in lst)
  • Я почти уверен, что это не так. В общем, это не оптимизирует вызовы сложных функций. int.Parse даже не является чистым в самом строгом смысле, поскольку он обращается к глобальному изменяемому состоянию, связанному с текущей культурой. CodesInChaos 02.12.2013
  • Во втором случае вам нужно var x = int.Parse(SomeStringProperty);. Исправьте и используйте эту опцию - вы никогда не можете быть уверены с JIT (это зависит от платформы и фазы Луны) Sergey Berezovskiy 02.12.2013
  • Я обычно предпочитаю второй подход, потому что он не вызывает функцию, и в любом случае это разбор строки (String = Slow почти в каждом случае (особенно если она длинная)). Я не уверен, что JIT оптимизирует его, но я не думаю (как он может управлять многопоточностью? Сохранить последнее изменение? Немного проверить?). Marco Acierno 02.12.2013
  • @lazyberezovsky Я согласен с фазой Луны JIT, но я думал, что первая оптимизация должна быть последовательной. в любом случае, вероятно, я воспользуюсь вторым вариантом Maya 02.12.2013
  • @MarcoLopezAcierno, это правда, потому что JIT выполняет оптимизацию также в многопоточном случае. см. здесь: albahari.com/threading/part4.aspx Maya 02.12.2013

optimizationjit

Ответы

Ответ 1 · рейтинг 8 · Marc Gravell

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

По сути, если вы хотите поднять его: поднимите его сами. Код во втором примере разумен (лично я бы добавил else, то есть else if).


Кроме того: ваш пример вызывает SomeStringProperty несколько раз : это тоже должно вызываться несколько раз, чтобы сохранить семантику, и может вести себя по-разному.

Наконец, в многопоточном мире само поле могло измениться.

Ответ 2 · рейтинг 1 · Marc Gravell

Об обновлении: этот пример совершенно не связан. Вы также можете привести пример:

var val = MyMethod.SomeMethod();

и сравните его с:

var tmp = MyMethod.SomeMethod();
var val = tmp;

в обоих случаях все, что вы сделали, это отделили вызов/оценку от использования путем присваивания промежуточной переменной. И в обоих случаях, если мы предположим, что переменная lst / tmp больше нигде не используется, мы можем быть достаточно уверены, что компилятор (не JIT) в любом случае действительно удалит эту переменную, так что они не просто логически эквивалентны - они фактически эквивалентны. В этом сценарии мы не удаляли никаких вызовов методов и т. д. - мы оцениваем их только один раз. Совершенно не связанный сценарий.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы