Поиск числа в массиве

dim3740
dim3740 аватар
Offline
Зарегистрирован: 25.03.2015

Есть два одномерных массива чисел к примеру,  int arr1[100] = {1, 54.....} и второй аналогичный. Я делаю математические операции с их элементами.

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

Подскажите, какие есть пути решения? Ускорит ли преобразования в строки и применение strstr? 

rkit
Онлайн
Зарегистрирован: 23.11.2016

Для быстрого поиска есть деревья и хеш-таблицы.

b707
Онлайн
Зарегистрирован: 26.05.2017

dim3740 пишет:

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

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

Может покажете код, а то что-то непонятно, где там у вас может быть затык

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

dim3740 пишет:

Есть два одномерных массива чисел к примеру,  int arr1[100] = {1, 54.....} и второй аналогичный. Я делаю математические операции с их элементами.

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

Подскажите, какие есть пути решения? Ускорит ли преобразования в строки и применение strstr? 

если число в конце массива хорошо справится шейкерный метод

b707
Онлайн
Зарегистрирован: 26.05.2017

ua6em пишет:

если число в конце массива хорошо справится шейкерный метод

если число в конце массива - надо искать с конца!

dim3740
dim3740 аватар
Offline
Зарегистрирован: 25.03.2015

b707 пишет:

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

Написан конечно криво... я только учусь)))

Счас вы подсказали, что производительности должно хватить на все с гаком.... поэтому ищу косяк в другом месте.

Так... массивы заполняются динамически с СОМ порт. Подскажите, плз, терминальную программу, которая может посылать НЕПРЕРЫВНО коды, которые я ввел в окно. ОФ...топик(((

 

rkit
Онлайн
Зарегистрирован: 23.11.2016

Что-то я не заметил, чтобы в теме было написано что есть "всё", чтобы знать, что производительности хватит на "всё"

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

ua6em пишет:

dim3740 пишет:

Есть два одномерных массива чисел...

Также есть задача нахождения индекса заданного числа.

если число в конце массива хорошо справится шейкерный метод

Это как?

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

andriano пишет:

ua6em пишет:

dim3740 пишет:

Есть два одномерных массива чисел...

Также есть задача нахождения индекса заданного числа.

если число в конце массива хорошо справится шейкерный метод

Это как?

кто у нас тут программисты?... обязаны знать )))

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

byte Array[100] = {0};

void setup() 
{
Array[99] = 45;            // делаем последнюю ячейку массива равной 45 например
Serial.begin (115200);

byte index45 = 0; 

uint32_t prevtime = micros(); // время начала поиска 
for (byte i=0; i<sizeof(Array); i++)
  {
   if (Array[i]==45){ index45 = i; break; }
  }
Serial.print (micros()-prevtime); // распечатаем сколько времени составил поиск
Serial.println (" microsec");

Serial.print ("Index45 = "); Serial.print (index45); 
 

}

void loop() {}

 

результат в терминале: 

52 microsec
Index45 = 99

52 микросекунды это много? 

 

b707
Онлайн
Зарегистрирован: 26.05.2017

52 мкс для этого - довольно много

Макс, а если в 11 строчке размер не вычислять, а  записать явно?

for (byte i=0; i<100; i++)

 

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

все равно 52

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

если массив int то 72 мкс, а если инкремент в цикле фор тоже сделать int то 88 мкс

b707
Онлайн
Зарегистрирован: 26.05.2017

MaksVV пишет:

все равно 52

да, точно... компилятор сам это заменяет при оптимизации...

b707
Онлайн
Зарегистрирован: 26.05.2017

а так?

byte Array[100] = {0};

void setup() 
{
Array[99] = 45;            // делаем последнюю ячейку массива равной 45 например
Serial.begin (115200);

byte index45 = 0; 

uint32_t prevtime = micros(); // время начала поиска 
for (byte i=0; i<sizeof(Array); i++)
  {
   if (Array[i]==45){ index45 = i; break; }
  }
prevtime = micros()-prevtime;
Serial.print (prevtime); // распечатаем сколько времени составил поиск
Serial.println (" microsec");

Serial.print ("Index45 = "); Serial.print (index45); 
 

}

void loop() {}

 

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

я тоже думал, что так будет быстрее и уже попробовал , все равно 52))  Понятно, что в реале поиск чуть меньше времени занимает, т.к. измерение времени поиска и распечатка тоже занимает время. Но, я думаю, может микросекунд на 5 поменьше. 

b707
Онлайн
Зарегистрирован: 26.05.2017

ну да, я тоже уже попробовал... :)

И через указатели вместо массива.. та же цифра с точностью до мкс.

Удивительная стабильность.

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

MaksVV пишет:


byte Array[100] = {0};

void setup() 
{
Array[99] = 45;            // делаем последнюю ячейку массива равной 45 например
Serial.begin (115200);

byte index45 = 0; 

uint32_t prevtime = micros(); // время начала поиска 
for (byte i=0; i<sizeof(Array); i++)
  {
   if (Array[i]==45){ index45 = i; break; }
  }
Serial.print (micros()-prevtime); // распечатаем сколько времени составил поиск
Serial.println (" microsec");

Serial.print ("Index45 = "); Serial.print (index45); 
 

}

void loop() {}

 

результат в терминале: 

52 microsec
Index45 = 99

52 микросекунды это много? 

 

конечно много, если всего одна строчка и можно сделать за 4 микросекунды )))
 

4 microsec
Index45 = 99
byte Array[100] = {0};

void setup() 
{
Array[99] = 45;            // делаем последнюю ячейку массива равной 45 например
Serial.begin (115200);

byte index45 = 0; 

uint32_t prevtime = micros(); // время начала поиска 
for (byte i=0; i<sizeof(Array); i++)
  {
   if (Array[i]==45){ index45 = i; break; }
   if (Array[100-i]==45){ index45 = 100 - i; break; }
  }
Serial.print (micros()-prevtime); // распечатаем сколько времени составил поиск
Serial.println (" microsec");

Serial.print ("Index45 = "); Serial.print (index45); 
 

}

void loop() {}

 

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

а если число в середине окажется? )) ну все равно чуть быстрее:  44 мкс. 

byte Array[100] = {0};

void setup() 
{
Array[50] = 45;            // делаем последнюю ячейку массива равной 45 например
Serial.begin (115200);

byte index45 = 0; 

uint32_t prevtime = micros(); // время начала поиска 
for (byte i=0; i<sizeof(Array); i++)
  {
   if (Array[i]==45){ index45 = i; break; }
   if (Array[100-i]==45){ index45 = 100 - i; break; }
  }
Serial.print (micros()-prevtime); // распечатаем сколько времени составил поиск
Serial.println (" microsec");

Serial.print ("Index45 = "); Serial.print (index45); 
 

}

void loop() {}

 

b707
Онлайн
Зарегистрирован: 26.05.2017

MaksVV пишет:

а если число в середине окажется? )) ну все равно чуть быстрее:  44 мкс.

ну да, только твой первый код находил 50-й элемент быстрее :)

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

MaksVV пишет:

а если число в середине окажется? )) ну все равно чуть быстрее:  44 мкс. 

byte Array[100] = {0};

void setup() 
{
Array[50] = 45;            // делаем последнюю ячейку массива равной 45 например
Serial.begin (115200);

byte index45 = 0; 

uint32_t prevtime = micros(); // время начала поиска 
for (byte i=0; i<sizeof(Array); i++)
  {
   if (Array[i]==45){ index45 = i; break; }
   if (Array[100-i]==45){ index45 = 100 - i; break; }
  }
Serial.print (micros()-prevtime); // распечатаем сколько времени составил поиск
Serial.println (" microsec");

Serial.print ("Index45 = "); Serial.print (index45); 
 

}

void loop() {}

 

да, но в этом случае если не применять шейкер, то оно найдётся быстрее, за
28 microsec
Index45 = 49

Тема обсосана мной лет 25 назад, в не сортированном массиве выигрывает быстрый поиск

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

MaksVV пишет:
Понятно, что в реале поиск чуть меньше времени занимает, т.к. измерение времени поиска и распечатка тоже занимает время. Но, я думаю, может микросекунд на 5 поменьше.

нифига подобного, проверил, закомментировал цикл фор. Показывает 0 мкс. Поэтому всё точно вплоть до 1 мкс. 

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

ua6em пишет:
да, но в этом случае если не применять шейкер, то оно найдётся быстрее, за

28 microsec
Index45 = 49

Тема обсосана мной лет 25 назад, в не сортированном массиве выигрывает быстрый поиск

не ну это повезло, мыж за максимальное время боремся, чтоб оно минимально было)) 

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

MaksVV пишет:

ua6em пишет:
да, но в этом случае если не применять шейкер, то оно найдётся быстрее, за

28 microsec
Index45 = 49

Тема обсосана мной лет 25 назад, в не сортированном массиве выигрывает быстрый поиск

не ну это повезло, мыж за максимальное время боремся, чтоб оно минимально было)) 

ждёмс, кто сподвигнется дописать быстрый поиск, мне в лом, я и не программист...мне книжку надо найти...открыть ...и алгоритм перенести в скетч )))

PS метод половинного деления тоже проигрывает

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

52 микросекунды на обработку 100 элементов - это по 8 тактов на элемент.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

MaksVV пишет:

а если число в середине окажется? )) ну все равно чуть быстрее:  44 мкс. 

byte Array[100] = {0};

void setup() 
{
Array[50] = 45;            // делаем последнюю ячейку массива равной 45 например
Serial.begin (115200);

byte index45 = 0; 

uint32_t prevtime = micros(); // время начала поиска 
for (byte i=0; i<sizeof(Array); i++)
  {
   if (Array[i]==45){ index45 = i; break; }
   if (Array[100-i]==45){ index45 = 100 - i; break; }
  }
Serial.print (micros()-prevtime); // распечатаем сколько времени составил поиск
Serial.println (" microsec");

Serial.print ("Index45 = "); Serial.print (index45); 
 

}

void loop() {}

 

Строго говоря, сразу надо уменьшать длину цикла вдвое (11 строка).

А выигрыш за счет того, что за проход цикла проверяется не 1, а 2 элемента. Меньше накладные расходы на организацию цикла. Если в цикле проверять по 10 элементов, будет еще быстрее. 

Собственно, расчет примерно такой:

- проверка окончания цикла - 2 такта,

- проверка, сравнение и переход - 6 тактов,

Если в цикле 1 сравнение - 8 тактов, если 2 сравнения - 14 тактов, но самих циклов вдвое меньше.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

ua6em пишет:

да, но в этом случае если не применять шейкер, то оно найдётся быстрее, за

28 microsec
Index45 = 49

Тема обсосана мной лет 25 назад, в не сортированном массиве выигрывает быстрый поиск

Нету никакого быстрого поиска. Шейкер - это метод сортировки, а не поиска.

ua6em пишет:

ждёмс, кто сподвигнется дописать быстрый поиск, мне в лом, я и не программист...мне книжку надо найти...открыть ...и алгоритм перенести в скетч )))

Фикция все это.

Поиск в неотсортированном массиве О(n). Быстрее не получится.

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

это похоже на разгон процессора под жидким азотом, только ради результата. Неужели эта цифра действительно большая ? ну что в нашем мире 52 мкс для любительского хобби? я delay по  100 200 мс, иногда не стремаюсь ставить в своих проектах. 

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

MaksVV пишет:

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

а вот когда обсчитывать надо 3 дома услуги ЖКХ на 286 машине и между расчётами тебе наливают, можно спиться, если не оптимизировать )))

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Собственно, листинг цикла:

for (byte i=0; i<sizeof(Array); i++)
 60c:	c0 e0       	ldi	r28, 0x00	; 0
  {
   if (Array[i]==45){ index45 = i; break; }
 60e:	81 91       	ld	r24, Z+
 610:	8d 32       	cpi	r24, 0x2D	; 45
 612:	21 f0       	breq	.+8      	; 0x61c <main+0x112>
Serial.begin (115200);

byte index45 = 0; 

uint32_t prevtime = micros(); // время начала поиска 
for (byte i=0; i<sizeof(Array); i++)
 614:	cf 5f       	subi	r28, 0xFF	; 255
 616:	c4 36       	cpi	r28, 0x64	; 100
 618:	d1 f7       	brne	.-12     	; 0x60e <main+0x104>
void setup() 
{
Array[99] = 45;            // делаем последнюю ячейку массива равной 45 например
Serial.begin (115200);

byte index45 = 0; 
 61a:	c0 e0       	ldi	r28, 0x00	; 0
uint32_t prevtime = micros(); // время начала поиска 
for (byte i=0; i<sizeof(Array); i++)
  {
   if (Array[i]==45){ index45 = i; break; }
  }
  uint32_t posttime = micros();
 61c:	0e 94 69 01 	call	0x2d2	; 0x2d2 <micros>

В регистре r28 у нас переменная цикла i, а в регистр r24 мы загружаем очередной элемент массива. Остальное, думаю, понятно: по адресу 610 сравниваем число с 45 и, если сравнение увенчалось успехом, следующим оператором покидаем цикл. По адресу 614 инкремент переменной цикла (сделан любопытно: i -= 255;), 616 - проверка на окончание цикла.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

MaksVV пишет:

я тоже думал, что так будет быстрее и уже попробовал , все равно 52))  Понятно, что в реале поиск чуть меньше времени занимает, т.к. измерение времени поиска и распечатка тоже занимает время. Но, я думаю, может микросекунд на 5 поменьше. 

Вроде как вывод одного символа в порт занимает 16мкс.
Так что не на 5.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Kakmyc пишет:
MaksVV пишет:

я тоже думал, что так будет быстрее и уже попробовал , все равно 52))  Понятно, что в реале поиск чуть меньше времени занимает, т.к. измерение времени поиска и распечатка тоже занимает время. Но, я думаю, может микросекунд на 5 поменьше. 

Вроде как вывод одного символа в порт занимает 16мкс. Так что не на 5.

Во-первых, вывод в порт в подсчет времени не входит, а во-вторых, Serial.print() не выводит символ в порт, а лишь помещает его в буфер вывода, что намного бысрее.

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

Kakmyc пишет:
Вроде как вывод одного символа в порт занимает 16мкс. Так что не на 5.

не, вывод ведь не влияет, если скетч внимательно посмотреть. Тем более я проверил, и микрос тоже не влияет. 

MaksVV пишет:

MaksVV пишет:
Понятно, что в реале поиск чуть меньше времени занимает, т.к. измерение времени поиска и распечатка тоже занимает время. Но, я думаю, может микросекунд на 5 поменьше.

нифига подобного, проверил, закомментировал цикл фор. Показывает 0 мкс. Поэтому всё точно вплоть до 1 мкс. 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

ua6em пишет:

4 microsec
Index45 = 99
byte Array[100] = {0};

void setup() 
{
Array[99] = 45;            // делаем последнюю ячейку массива равной 45 например
Serial.begin (115200);

byte index45 = 0; 

uint32_t prevtime = micros(); // время начала поиска 
for (byte i=0; i<sizeof(Array); i++)
  {
   if (Array[i]==45){ index45 = i; break; }
   if (Array[100-i]==45){ index45 = 100 - i; break; }
  }
Serial.print (micros()-prevtime); // распечатаем сколько времени составил поиск
Serial.println (" microsec");

Serial.print ("Index45 = "); Serial.print (index45); 
 

}

void loop() {}

Ну,  детские ошибки-то исправьте!

1. за границы массива-то не надо вылазить!

2. Вы в цикле сравниваете с начала и с конца, но при этом нафига-то идёте черезь весь массив! Т.е. если искомого элемента в массиве нет, то Вы каждый элемент сравните с 45 ДВАЖДЫ!

3. В ограничении цикла нельзя использовать sizeof - это сработает только при байтовом массиве чисто по совпадению. При любом другом типе (int, long) всё повалится нахрен.

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

andriano пишет:

 По адресу 614 инкремент переменной цикла (сделан любопытно: i -= 255;), 616 - проверка на окончание цикла.

интересно почему так?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Не знаю.

В принципе, для байта "i++;" и "i -=255;" - это одно и то же. Может автор дизассемблера так самовыразился. А может - чтобы флаги состояния после операции правильно расставились. Я не силен в системе команд AVR.

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

ua6em пишет:

Ну,  детские ошибки-то исправьте!

 

тут народ почему-то не знает, что такое шейкер, писал не мудрствуя лукаво и на ошибки забил )))

так видимо будет правильней:
 

byte Array[100] = {0};

void setup() 
{
Array[89] = 45;            // делаем последнюю ячейку массива равной 45 например
//Array[49] = 45;
Serial.begin (115200);

byte index45 = 0; 

uint32_t prevtime = micros(); // время начала поиска 
for (byte i=0; i<50; i++)
  {
   if (Array[i]==45){ index45 = i; break; }
   if (Array[99-i]==45){ index45 = 99 - i; break; }
  }
Serial.print (micros()-prevtime); // распечатаем сколько времени составил поиск
Serial.println (" microsec");

Serial.print ("Index45 = "); Serial.print (index45); 
 

}

void loop() {}

кстати, даже для самого тяжёлого случая поиск занимает 48 микросекунд на ниже приведённом скетче, может покажете быстрый поиск?
 

byte Array[100] = {0};

void setup() 
{
Array[24] = 45;            // делаем последнюю ячейку массива равной 45 например
Serial.begin (115200);

byte index45 = 0; 

uint32_t prevtime = micros(); // время начала поиска 
for (byte i=0; i<25; i++)
  {
   if (Array[i]==45){ index45 = i; break; }
   if (Array[49-i]==45){ index45 = 49 - i; break; }
   if (Array[i+50]==45){ index45 = i+50; break; }
   if (Array[99 -i]==45){ index45 = 99 - i; break; }
  }
Serial.print (micros()-prevtime); // распечатаем сколько времени составил поиск
Serial.println (" microsec");
Serial.print ("Index45 = "); Serial.print (index45); 
}

void loop() {}

 

rkit
Онлайн
Зарегистрирован: 23.11.2016

Да напиши уж сразу все сто сравнений на if, гений программирования блин.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

ua6em пишет:

кстати, даже для самого тяжёлого случая поиск занимает 48 микросекунд на ниже приведённом скетче, может покажете быстрый поиск?

Быстрого поиска по неупорядоченному массиву не существует. Нужно либо сортировать массив, либо использовать деревья. В любом случае O(log(N)).

Но Вы на правильном пути: 

uint32_t prevtime = micros(); // время начала поиска 
if (Array[0]==45){ index45 = 0; break; }
if (Array[1]==45){ index45 = 1; break; }
if (Array[2]==45){ index45 = 2; break; }
if (Array[3]==45){ index45 = 3; break; }
if (Array[4]==45){ index45 = 4; break; }
...
if (Array[99]==45){ index45 = 99; break; }
Serial.print (micros()-prevtime); // распечатаем сколько времени составил поиск

 

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

rkit пишет:

Да напиши уж сразу все сто сравнений на if, гений программирования блин.

а пальцем показать сможешь? или ты всё языком?
 

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

byte Array[100] = {0};

void setup() 
{
Serial.begin (115200);
randomSeed(analogRead(0));
uint8_t s = random(100);
Array[s] = 45;            // делаем последнюю ячейку массива равной 45 например


byte index45 = 0; 

uint32_t prevtime = micros(); // время начала поиска 
for (byte i=0; i<25; i++)
  {
   if (Array[i]==45){ index45 = i; break; }
   if (Array[49-i]==45){ index45 = 49 - i; break; }
   if (Array[i+50]==45){ index45 = i+50; break; }
   if (Array[99 -i]==45){ index45 = 99 - i; break; }
  }
Serial.print (micros()-prevtime); // распечатаем сколько времени составил поиск
Serial.println (" microsec");
Serial.print ("Index45 = "); Serial.println (index45); 
}

void loop() {}

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016


получается, что компилятор реализует функцию весьма эффективно, на ассемблере это было бы
приблизительно 5-8 инструкций, то-есть 35-56  микросекунд приблизительно, переводом на ассемблер
не решить задачу, остаётся только алгоритм...

Voodoo Doll
Voodoo Doll аватар
Offline
Зарегистрирован: 18.09.2016

ua6em пишет:
а вот когда обсчитывать надо 3 дома услуги ЖКХ на 286 машине и между расчётами тебе наливают

Тому кто технарям ставит задачу по ЖКХ и даёт 286 машины надо в рот насрать.

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Voodoo Doll пишет:

ua6em пишет:
а вот когда обсчитывать надо 3 дома услуги ЖКХ на 286 машине и между расчётами тебе наливают

Тому кто технарям ставит задачу по ЖКХ и даёт 286 машины

так дело давно было, на заре автоматизации )))

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

ua6em пишет:



получается, что компилятор реализует функцию весьма эффективно, на ассемблере это было бы
приблизительно 5-8 инструкций

Ассемблерный листинг был размещен в сообщении №29.

Так что, кто умеет читать - читает, а кто не умеет - гадает, сколько это приблизительно могло бы быть.

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

andriano пишет:

ua6em пишет:



получается, что компилятор реализует функцию весьма эффективно, на ассемблере это было бы
приблизительно 5-8 инструкций

Ассемблерный листинг был размещен в сообщении №29.

Так что, кто умеет читать - читает, а кто не умеет - гадает, сколько это приблизительно могло бы быть.

вот это что ли?
 

for (byte i=0; i<sizeof(Array); i++)
02
	 60c:   c0 e0           ldi r28, 0x00   ; 0

 

конечно не умею, не вижу тут размерности массива, совсем...

посмотрел внимательней, сделано через взад, а чё, так тоже можно, особенно в свете общемировых тенденций...

 614:	cf 5f       	subi	r28, 0xFF	; 255
 616:	c4 36       	cpi	r28, 0x64	; 100

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

ua6em пишет:

посмотрел внимательней, сделано через взад, а чё, так тоже можно, особенно в свете общемировых тенденций...

 614:	cf 5f       	subi	r28, 0xFF	; 255
 616:	c4 36       	cpi	r28, 0x64	; 100

subi r28,ff и  inc r28 оба занимают 2 байта, как любая команда, выполняются ОДИН так и делают ОДНО И ТОЖЕ. Только SUBI больше флагов выставляет. Поэтому компилятор её и предпочитает. Нет аргументов в пользу inc, кроме "читаемости человеком". Как ты думаешь, компилятору важна "читаемость" человеком его кода? ;))))

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

wdrakula пишет:

ua6em пишет:

посмотрел внимательней, сделано через взад, а чё, так тоже можно, особенно в свете общемировых тенденций...

 614:	cf 5f       	subi	r28, 0xFF	; 255
 616:	c4 36       	cpi	r28, 0x64	; 100

subi r28,ff и  inc r28 оба занимают 2 байта, как любая команда, выполняются ОДИН так и делают ОДНО И ТОЖЕ. Только SUBI больше флагов выставляет. Поэтому компилятор её и предпочитает. Нет аргументов в пользу inc, кроме "читаемости человеком". Как ты думаешь, компилятору важна "читаемость" человеком его кода? ;))))

я учил ассемблер по книге Питера Нортона, меня не переделать уж

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

ua6em пишет:

я учил ассемблер по книге Питера Нортона, меня не переделать уж

Долго думал, что в ответ написать. Ничего кроме:

--Возьми с полки порожок! 

не пришло в голову! ;)))

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

ua6em пишет:

wdrakula пишет:

ua6em пишет:

посмотрел внимательней, сделано через взад, а чё, так тоже можно, особенно в свете общемировых тенденций...

 614:	cf 5f       	subi	r28, 0xFF	; 255
 616:	c4 36       	cpi	r28, 0x64	; 100

subi r28,ff и  inc r28 оба занимают 2 байта, как любая команда, выполняются ОДИН так и делают ОДНО И ТОЖЕ. Только SUBI больше флагов выставляет. Поэтому компилятор её и предпочитает. Нет аргументов в пользу inc, кроме "читаемости человеком". Как ты думаешь, компилятору важна "читаемость" человеком его кода? ;))))

я учил ассемблер по книге Питера Нортона, меня не переделать уж

А я по Питеру Абелю. Чье кунфу сильнее? :-)

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

DetSimen]</p> <p>[quote=ua6em пишет:

wdrakula пишет:

А я по Питеру Абелю. Чье кунфу сильнее? :-)

скорее твоё, тогда у процессора уровней ещё небыло