Задача состоит в том, чтобы найти способ нарисовать горизонтальную линию в массиве 16-битных целых чисел.
Мы предполагаем массив 256x192 пикселей с 16 пикселями на слово. Строка - это непрерывный набор битов (1). Строки могут начинаться с середины любого слова, накладываться на любые другие слова и заканчиваться на любом слове; они также могут начинаться и заканчиваться одним и тем же словом. Они не могут переходить на следующую строку. Подсказка: средние слова просты - просто напишите 0xffff, но края будут хитрыми, как и обработка случая для начала и конца в одном и том же слове. Функция / процедура / подпрограмма должна принимать координаты x0 и x1, указывающие точки начала и конца по горизонтали, а также координату yy.
Я исключаю себя из этого, потому что я сам разработал почти идентичный алгоритм для встроенного процессора, но мне любопытно, как другие поступят по этому поводу. Бонусные баллы за использование относительно быстрых операций (например, операция 64-битного умножения или с плавающей запятой не будет быстрой на встроенной машине, но будет простой сдвиг битов).
источник
Ответы:
В этом коде предполагается, что и x0, и x1 являются включающими конечными точками, а слова имеют порядок байтов (т. Е. Можно установить (0,0) пиксель
array[0][0]|=1
).источник
питон
Основной трюк здесь заключается в использовании таблицы поиска для хранения битовых масок пикселей. Это экономит несколько операций. В наши дни таблица размером 1 КБ невелика даже для встроенной платформы
Если места действительно мало, по цене пары & 0xf справочную таблицу можно уменьшить до 64B
Этот код написан на Python, но его было бы просто перенести на любой язык, который поддерживает битовые операции.
Если вы используете C, вы можете рассмотреть возможность размотки петли с помощью устройства
switch
от Даффа . Поскольку ширина строки не более 16 слов, я бы расширил ееswitch
до 14 строк иwhile
вообще отказался от нее.источник
Вот C-версия моего Python-ответа с использованием оператора switch вместо цикла while и уменьшением индексации путем увеличения указателя вместо индекса массива
Размер таблицы поиска может быть существенно уменьшен при использовании T [x1 & 0xf] и U [x2 & 0xf] для пары дополнительных инструкций
источник
Скала,
линии 7 с / 1М, строки4.1 с / 1Мпервая реализация:
После устранения внутреннего вызова метода и замены цикла for с помощью цикла while на моем одноядерном 2Ghz Scala 2.8 он освобождает 1 Mio. Строки за 4.1сек. вместо начальных 7с.
Тест-код и вызов:
Тестирование производительности:
Протестировано с использованием инструмента Unix, сравнивая время пользователя, включая время запуска, скомпилированный код, отсутствие фазы запуска JVM.
Увеличение количества строк показывает, что на каждый новый миллион требуется дополнительно 3,3 с.
источник