Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 17.05.2016, 12:43   #1
OmegaBerkut
Спокойный псих
Участник клуба
 
Аватар для OmegaBerkut
 
Регистрация: 19.03.2013
Сообщений: 1,538
По умолчанию Оптимизация кода

Всем привет.
Помогите пожалуйста оптимизировать нижеследующий код на скорость выполнения.
Код:
private bool CheckToData(string number)
{
	int length=number.Length,i; // так быстрее
	if (length % 2!=0)
		return false;
	char checkch; // так тоже быстрее
	for (i=0;i<length;i++)
	{
		checkch=number[i];
		if (checkch==ch0 || checkch==ch1 || checkch==ch2 ||
				checkch==ch3 || checkch==ch4 || checkch==ch5)
			return false;
	}
	// поиск вхождений через String.IndexOf() происходят немного медленнее
	// поиск через String.IndexOfAny() гораздо медленнее
	string reverse="";
	for (i=length-1;i>-1;i--) // быстрее, чем char[] и Array.Reverse()
		reverse+=number[i];
	return (number==reverse);
}

private void Thread1() // таких ещё четыре (мощностя и условия требуют распределения)
{
	string testdata;
	count1=0; // инициализация внешних данных
	outdata1=""; // инициализация внешних данных
	Stopwatch time=new Stopwatch(); // отладочная проверка скорости работы
	time.Start();
	for (long i=0;i<=2000000000;i++) // в остальных четырёх потоках проверяются следующие два миллиарда; всего 10 миллиардов, плюс 1 111 111 110 "неофициальных"
	{
		state1=0; // индикация о состоянии выполнения (данные забираются из главного потока раз в секунду)
		testdata=i.ToString();
		if (CheckToData(testdata))
		{
			count1++;
			outdata1+=testdata+" ";
		}
		while (testdata.Length<10) // те самые 222 222 222 ("неофициальных") значения на один поток
		{
			testdata="0"+testdata;
			if (CheckToData(testdata))
			{
				count1++;
				outdata1+=testdata+" ";
			}
		}
		if (time.Elapsed.Ticks>=10000000) / это одна секунда в тактах
		{ // тут точка останова для отладчика
		}
	}
	time.Stop();
}
У каждого потока свои внешние данные, которые после выполнения всех потоков дружно отправляются в файл.
Так же не обнаружил разницы между i++ и ++i в циклах.
Мой процессор - Intel Core i7 3630QM (ноутбук), 8 ядер (4 физических, 4 виртуальных), 2,4 GHz на ядро.
Этот код загружает все 8 ядер на 90%. Примерная скорость работы в отладчике (Stopwatch) = 1 000 000 значений в секунду.
После выполнения пяти потоков формируются новые данные ch0-ch5 (берутся из файла), и всё по новой. Всего 210 наборов значений ch0-ch5.
Из всего этого следует, что при номинальной нагрузке процессора непрерывный перебор будет длиться около пяти суток (2000 секунд один поток, помноженные на 210). Это при том, что приоритеты потоков установлены в Highest, приоритет процесса установлен в RealTime, IsBackground для всех потоков равен false.

Мало того, я не горю желанием так сильно и так долго грузить процессор (износ, все дела). Так что периодически я буду ставить выполнение всех потоков на паузу, и отправлять компьютер в спящий режим. А что бы компьютер можно было использовать для повседневных нужд - нужно добавить управление приоритетами потоков и процесса.
Итого я могу получить время выполнения до 15 суток.
Хотелось бы сократить всё это дело, и я буду благодарен вам за любую вашу помощь.

Приветствуются любые идеи, которые позволят мне ускорить перебор.
Подпись ? Не, не слышал ...
OmegaBerkut вне форума Ответить с цитированием
Старый 17.05.2016, 13:47   #2
OmegaBerkut
Спокойный псих
Участник клуба
 
Аватар для OmegaBerkut
 
Регистрация: 19.03.2013
Сообщений: 1,538
По умолчанию

Новая информация: вне отладчика пять таких потоков выполняются за 13 минут. То есть, непрерывное выполнение перебора 210 вариантов будет длиться 45 с половиной часов. Уже быстрее, чем в отладчике. Пока перебор выполняется ...
Подпись ? Не, не слышал ...
OmegaBerkut вне форума Ответить с цитированием
Старый 17.05.2016, 13:52   #3
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

to CheckToData

или 2 цикла
Код:
	for i=0; i<length; i++)
	{
          switch number[i]
          '4', '5', '6', '7': {break; }
          else { return false }
        }  

	for (i=0; i<length % 2; i++)
	{  if number[i] <>number[length-i] 
           {return false}
        }
или один
Код:
	for i=0; i<length; i++)
	{
          switch number[i]
          '4', '5', '6', '7': {break; }
          else { return false };

	  if number[i] <>number[length-i] 
          {return false}
        }
КАКОВА исходная задача ?
ПОЛУЧИТЬ ВСЕ числа удовлетворяющие ВСЕМ сразу условиям ????
0. НЕ более 10 знаков включая ВЕДУЩИЕ нули (1; 01; 001; ... )
1. только 4,5,6,7 (значит НИКАКИХ нулей ?)
2. только четная длина
3. только палиндром
взято отсюда
+ прочтение ChecktoData.

гораздо проще генерить только нужное
ОТВЕТ без потоков

Код:
mas[1]='4'; mas[2]='5'; mas[3]='6'; mas[4]='7';
for (i0=1; i0<5; i0++)
for (i1=1; i1<5; i1++)
for (i2=1; i2<5; i2++)
for (i3=1; i3<5; i3++)
for (i4=1; i4<5; i4++)
  num =mas[i0] +mas[i1] +mas[i2] +mas[i3] +mas[i4] +mas[i4] +mas[i3] +mas[i2] +mas[i1] +mas[i0]; //палиндром по построению; длина =10; и значит четная; цифры из разрешенного спсика(4;5;6;7)
// количество таких 4{длина массива mas}**5{количество рабочих(вложенных) циклов} =2*10 =1024
 
for (i0=1; i0<5; i0++)
for (i1=1; i1<5; i1++)
for (i2=1; i2<5; i2++)
for (i3=1; i3<5; i3++)
//for (i4=1; i4<5; i4++)
  num =mas[i0] +mas[i1] +mas[i2] +mas[i3] /*+mas[i4] +mas[i4]*/ +mas[i3] +mas[i2] +mas[i1] +mas[i0]; //палиндром по построению; длина =8; и значит четная; цифры из разрешенного спсика(4;5;6;7)
// количество таких 4**4 =2*8 =256

for (i0=1; i0<5; i0++)
for (i1=1; i1<5; i1++)
for (i2=1; i2<5; i2++)
//for (i3=1; i3<5; i3++)
//for (i4=1; i4<5; i4++)
  num =mas[i0] +mas[i1] +mas[i2] /*+mas[i3] +mas[i4] +mas[i4] +mas[i3]*/ +mas[i2] +mas[i1] +mas[i0]; //палиндром по построению; длина =6; и значит четная; цифры из разрешенного спсика(4;5;6;7)
// количество таких 4**3 =2*6 =64

for (i0=1; i0<5; i0++)
for (i1=1; i1<5; i1++)
//for (i2=1; i2<5; i2++)
//for (i3=1; i3<5; i3++)
//for (i4=1; i4<5; i4++)
  num =mas[i0] +mas[i1] /*+mas[i2] +mas[i3] +mas[i4] +mas[i4] +mas[i3] +mas[i2]*/ +mas[i1] +mas[i0]; //палиндром по построению; длина =4; и значит четная; цифры из разрешенного спсика(4;5;6;7)
// количество таких 4**2 =2*4 =16

for (i0=1; i0<5; i0++)
//for (i1=1; i1<5; i1++)
//for (i2=1; i2<5; i2++)
//for (i3=1; i3<5; i3++)
//for (i4=1; i4<5; i4++)
  num =mas[i0] /*+mas[i1] +mas[i2] +mas[i3] +mas[i4] +mas[i4] +mas[i3] +mas[i2] +mas[i1]*/ +mas[i0]; //палиндром по построению; длина =2; и значит четная; цифры из разрешенного спсика(4;5;6;7)
// количество таких 4**1 =2*2 =4
Код:
1024
 256
  64
  16
   4
----
1364
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 17.05.2016 в 14:13.
evg_m вне форума Ответить с цитированием
Старый 17.05.2016, 14:06   #4
OmegaBerkut
Спокойный псих
Участник клуба
 
Аватар для OmegaBerkut
 
Регистрация: 19.03.2013
Сообщений: 1,538
По умолчанию

evg_m
Условия следующие:
0. НЕ более 10 знаков включая ВЕДУЩИЕ нули (1; 01; 001; ... )
1. только 4,5,6,7 (и с нулями тоже, и не только 4 5 6 7); вариант 00455400 тоже должен учитываться
2. только четная длина
3. только палиндром
Подпись ? Не, не слышал ...
OmegaBerkut вне форума Ответить с цитированием
Старый 17.05.2016, 14:18   #5
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

Цитата:
1. только 4,5,6,7 (и с нулями тоже, и не только 4 5 6 7); вариант 00455400 тоже должен учитываться
т.е. нули могут быть где?
просто могут быть.
Увеличиваете длину mas (добавляете туда mas[5]='0')
+ другие границы ВСЕХ циклов.
Код:
for (i0=low(mas){нижняя граница}; i0<=high(mas){верхняя граница}; i0++)
Есть определенные условия на нули.
+ Добавляете условие проверки либо на num
Код:
if Check(num) {  add(num) }
либо на входЫ в циклы
Код:
if mas[i0]='0' for (i1=low(mas); i1<=high(mas); i1++) ..........
else for (i1=low(mas); i1<high(mas){здесь НОЛЯ быть не может}; i1++)
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 17.05.2016 в 14:25.
evg_m вне форума Ответить с цитированием
Старый 17.05.2016, 15:53   #6
OmegaBerkut
Спокойный псих
Участник клуба
 
Аватар для OmegaBerkut
 
Регистрация: 19.03.2013
Сообщений: 1,538
По умолчанию

Нули могут быть там, где они допущены символами, которые по коду не равны ch0-ch5.
Мне тяжело словесно оформить условия. В приведённом мною коде всё правильно работает, и на выходе я получаю наборы нужных мне чисел.
Первые 20 чисел для набора 0 1 2 3:
00 0000 000000 00000000 0000000000 11 22 33 0110 0220 0330 1001 001100 1111 1221 1331 2002 2112 002200 2222
Подпись ? Не, не слышал ...
OmegaBerkut вне форума Ответить с цитированием
Старый 17.05.2016, 16:05   #7
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

Цитата:
где они допущены символами,
Цитата:
просто могут быть.
и далее по предыдущему ПОСТУ.
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
оптимизация кода Programmer121 Общие вопросы C/C++ 7 12.01.2016 17:37
Оптимизация кода (C++) Кирилл Романов Помощь студентам 0 30.10.2013 23:36
Оптимизация кода на C# FiloXSee Общие вопросы .NET 4 24.09.2011 17:10
Оптимизация кода LuckyTheGreat C# (си шарп) 3 15.07.2011 00:46
Оптимизация кода WoWan-SM Общие вопросы .NET 4 27.04.2010 11:33