C Программирование: различие между ++ я и i=i+1 с ассемблерной точки зрения?

Первый подход: с использованием tf.one_hot и tf.boolean_mask:

# shape = (?,1,3)
mask_idx = 1- tf.one_hot(idx,a.shape[1])
# shape = (?,3)
result = tf.boolean_mask(a,mask_idx[:,0,:])
# shape = (?,2,3)
result = tf.reshape(result,shape=(-1,a.shape[1]-1,a.shape[2]))

Второй подход: с использованием tf.map_fn:

result = tf.map_fn(lambda x: tf.boolean_mask(x[0],1 - tf.one_hot(tf.squeeze(x[1]),a.shape[1]))
                   , [a,idx]
                   , dtype=tf.int32)

Пример:

import tensorflow as tf

a = tf.constant([[[1,2,3],[4,5,6],[7,8,9]],
                    [[9,8,7],[6,5,4],[3,2,1]],
                    [[0,8,0],[1,5,4],[3,1,1]]],dtype=tf.int32)
idx = tf.constant([[1],[0],[2]],dtype=tf.int32)

# First approach:
# shape = (?,1,3)
mask_idx = 1- tf.one_hot(idx,a.shape[1])
# shape = (?,3)
result = tf.boolean_mask(a,mask_idx[:,0,:])
# shape = (?,2,3)
result = tf.reshape(result,shape=(-1,a.shape[1]-1,a.shape[2]))

# Second approach:
result = tf.map_fn(lambda x: tf.boolean_mask(x[0],1 - tf.one_hot(tf.squeeze(x[1]),a.shape[1]))
                   , [a,idx]
                   , dtype=tf.int32)

with tf.Session() as sess:
    print(sess.run(result))

# print
[[[1 2 3]
  [7 8 9]]

 [[6 5 4]
  [3 2 1]]

 [[0 8 0]
  [1 5 4]]]
16
задан sharptooth 15 May 2009 в 09:22
поделиться

6 ответов

Интервьюер, возможно, хотел получить ответ примерно так:

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

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

19
ответ дан 30 November 2019 в 15:52
поделиться

Похоже, вы были правы, а они ошибались. У меня была аналогичная проблема на собеседовании, когда я дал правильный ответ, который посчитали неправильным.

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

10
ответ дан 30 November 2019 в 15:52
поделиться

Вы, наверное, правы. Наивный компилятор мог бы сделать:

++i to inc [ax]

и

i = i + 1 to add [ax], 1

, но любой наполовину разумный компилятор просто оптимизирует добавление 1 к первой версии.

Все это предполагает, что соответствующая архитектура имеет инструкции inc и add (как это делает x86).

8
ответ дан 30 November 2019 в 15:52
поделиться

Чтобы защитить интервьюера, контекст решает все. Какой тип я? Мы говорим о C или C ++ (или о каком-то другом языке, подобном C)? Вам дали:

++i;
i = i + 1;

или был еще контекст?

Если бы меня спросили об этом, мой первый ответ был бы "Я изменчив?" Если да, то разница огромна. Если нет, то разница небольшая и смысловая, но с практической точки зрения нет. Доказательством этого является различие в дереве синтаксического анализа и окончательное значение сгенерированных поддеревьев.

Похоже, вы правильно поняли прагматическую сторону, но ошиблись с семантической / критической стороной мышления.

Напасть на интервьюера. (без контекста), мне бы хотелось задаться вопросом, в чем была цель вопроса. Если бы я задал вопрос, я бы хотел использовать его, чтобы узнать, знает ли кандидат тонкие семантические различия, как создать дерево синтаксического анализа, как мыслить критически и так далее, и так далее. Я обычно задаю респондентам вопрос C, который почти каждый кандидат ошибается - и это намеренно. На самом деле меня не волнует ответ на вопрос, меня волнует путешествие, которое я предприму с кандидатом , чтобы достичь понимания, которое говорит мне гораздо больше, чем о правильном / неправильном в пустяковом вопросе .

7
ответ дан 30 November 2019 в 15:52
поделиться

В C ++ это зависит от того, является ли i целым числом или объектом. Если это объект, вероятно, будет создан временный экземпляр.

3
ответ дан 30 November 2019 в 15:52
поделиться

контекст является здесь главным, потому что при оптимизированной сборке выпуска компилятор оптимизирует i ++, если он доступен для простого [inc eax]. тогда как что-то вроде int some_int = i ++ необходимо сохранить значение i в some_int FIRST и только затем увеличивать i.

0
ответ дан 30 November 2019 в 15:52
поделиться
Другие вопросы по тегам:

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