2015-01-26 2 views
4

У меня есть набор кодов клавиш со значениями (конечно, 4), от 0 до 3, соответствующих клавишам вниз, влево, вверх, вправо, в том заказ. Мне нужно преобразовать эти коды ключей в x и y направления, с положительным x, указывающим местоположение слева от начала координат, и положительное y, указывающее местоположение ниже начала координат. Как я понимаю, у меня есть два способа сделать это:самый эффективный способ изменения int в направлении X и Y

с использованием массивов:

int [] dx = {0, -1, 0, 1}; 
int [] dy = {1, 0, -1, 0}; 
int x = dx[kc]; 
int y = dy[kc]; 

или с помощью арифметического:

int x = (kc%2)*(((kc/2)%2)*2 - 1); 
int y = ((kc+1)%2)*(((kc/2)%2)*-2 + 1); 

, который был бы более эффективным?

+0

Разница в эффективности очень незначительна. Что вам более читаемо? – Kon

+0

не делайте преждевременной оптимизации, подождите, пока этот метод не появится в вашем профилировщике – Mysterion

+0

Как сказал @Kon, это очень незначительно. Функции памяти немного менее эффективны, поскольку им необходимо получить доступ к памяти, тогда как арифметика обрабатывается в ALU на CPU. Не так уж и важно, что вы должны беспокоиться об этом, если только вы не работаете над проектом, где время выполнения Чрезвычайно важно. –

ответ

1

Возможно, это зависит от языка. Я думаю, что целочисленное представление будет более эффективным. Или еще лучше, если вам нужно пространство, вы можете представлять направления с битовыми строками. Вам понадобится 4 бита для четырех направлений. Большинство ints составляют 4 байта, что составляет 8-кратное хранилище! Опять же, это, вероятно, ничего не скажется, если вы не храните много из них.

Я бы выделил представление с помощью методов направления (getDirection(), setDirection() и т. Д.), А затем попробуйте запустить вашу программу с несколькими различными типами.

Редактировать: woops, я хотел сделать это комментарием, а не ответом. Извини за это.

1

Профилирование было бы вашим другом, но я разделил бы ваши константы по-другому. Рассмотрим:

private static final int[][] directions = { 
    {0, 1}, 
    {-1, 0}, 
    {0, -1}, 
    {1, 0} 
}; 

Тогда вы можете сделать это так же просто:

x = directions[kc][0]; 
y = directions[kc][1]; 
1

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

Если производительность важна, и этот фрагмент кода имеет решающее значение, вы должны фактически сравнить два подхода. Используйте что-то вроде google caliper.

Во-вторых, вы можете оптимизировать второй подход, заменяя (несколько медленно) операцию по модулю с логическим И (x &= 0xfffffffe такая же, как x%=2 только быстрее, предполагая, что x является Int). И заменив умножение на 2 на логический сдвиг влево (так x < < 1 вместо x * 2).

0

Вот еще один способ сделать преобразование.

package com.ggl.testing; 

import java.awt.Point; 

public class Convert { 

    public Point convertDirection(int index) { 
     // 0 to 3 corresponds to the keys down, left, up, right 
     Point[] directions = { new Point(0, 1), new Point(-1, 0), 
       new Point(0, -1), new Point(1, 0) }; 
     return directions[index]; 
    } 

} 
Смежные вопросы