Ken Guru Ответов: 2

Как мне решить эту проверку состояния более математическим способом?


Привет,

могу ли я решить эту проблему:
private static string _positions;

//Initialize _positions with '1' depending on items (up to 500 items)
_positions = new string('1', items);

//If a certain condition is fulfilled, then set the index of that specific item to blank
_positions = new StringBuilder(_positions) { [i] = ' ' }.ToString();

//Test _positions for whitespace, then all items handled 
if (string.IsNullOrWhiteSpace(_positions))
{
	DoSomething();
}

с чем-то вроде BitArray и теста на 0 или что-то подобное? Это должно быть значительно быстрее. Моя проблема-это до 500 предметов.

Заранее спасибо

Что я уже пробовал:

Это и другие известные решения. Но моя проблема заключается в большом количестве предметов для тестирования.

2 Ответов

Рейтинг:
14

CPallini

Напишите класс, содержащий массив целых чисел (или что-то еще), скажем arr. Конструктор будет установить все элементы массива в состояние по умолчанию (скажем 0) и counter переменной 0.
Затем укажите метод изменения элемента, скажем setOne(int index).
На каждом из них setOne звоните, если товар есть 0 затем он изменяется на 1 и counter увеличено; с другой стороны, если оно уже 1 и тогда ничего не происходит.

Тогда "глобальный пустой" тест сводился бы к следующему: (counter == arr.Length).


Рейтинг:
0

Ken Guru

Привет CPallini,

хорошее решение. Большое спасибо! Вот мой получившийся код:

static internal class PositionCheck
{
  static private int _counter;
  static internal int Counter { get => _counter; }
  static private char[] _arr;

  static internal void SetItemCount(int items)
  {
     _arr = new char[items];
     _counter = items;
  }

  static internal void Set(int index)
  {

	 if(_arr[index] == '\0')
	 {
		_arr[index] = '1';
		_counter--;
	 }
  }

  static internal bool Get(int index)
  {
	 return _arr[index] == '\0';
  }
}

Кругозор


CPallini

То есть, молодец. Интересно, если использовать ints вместо chars ускорит код (в дополнение к потере памяти, конечно).
Кстати, вы проводили бенчмарк по сравнению с вашим исходным кодом?

CPallini

[От имени Кена гуру]
Я думаю, что ваше решение быстрее. Проверка на наличие строки.IsNullOrWhiteSpace() сам по себе должен быть медленнее, потому что внутренне все позиции символов должны быть повторены и протестированы (я думаю). В вашем решении только счетчик должен быть проверен на 0, тем более что ваше решение хорошо масштабируется и работает даже со 100.000 записями. Я не проверял, дает ли переход от char к int еще одно значительное преимущество в скорости.

Кругозор

Ken Guru

Теперь я тестирую это с 1000 раундами с 10.000.000!!! элементы одновременно на ядре i7 8700k @5GHz.

С char[] ~ 48,67 МС
С int[] ~ 52,91 МС

Только из 200.000 элементов значение выше 0 мс вообще заметно в секундомере.
Исходное решение слишком медленное: 6.500 элементов в этом решении работают так же быстро, как 10.000.000.
:)

CPallini

Отлично сработано. Я предполагал обратное. Однако, по-видимому, "размер имеет значение".

CPallini

Пожалуйста, публикуйте ответы на комментарии с помощью кнопки "Ответить", а не добавляйте ложные решения.

Ken Guru

Понял :)