Как я могу эффективно испачкать части массива?

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

В настоящее время я работаю на C++, но думаю, что этот вопрос относится к большинству компилируемых языков.

В моем проекте у меня есть массив значений, которые рассчитываются индивидуально, по одному, как можно позже на основе одной переменной. Эти значения не вычисляются сразу, они вычисляются тогда и только тогда, когда это необходимо. Как это обычно бывает при использовании «грязного», цель состоит в том, чтобы пометить определенные вещи как нуждающиеся в обновлении, без предварительного обновления. Эти значения циклически меняются снова и снова, поэтому я хотел бы кэшировать вычисления, если это возможно. Всякий раз, когда изменяется одна переменная, все значения должны быть помечены как грязные, чтобы цикл знал, что нужно пересчитать, прежде чем сохранять и двигаться дальше.

Я могу придумать несколько способов добиться этого, но не уверен, какой из них наиболее эффективен:

  1. Имейте два массива, один из логических значений и один из значений. Пометьте все логические значения как ложные, если они грязные, и как истинные, если они чистые.
  2. Иметь чистую стартовую точку. Считайте все грязным, пока снова не пройдете эту точку цикла. Имеет недостаток в том, что не позволяет пропускать записи цикла.
  3. Совершенно новый массив. Просто создайте новый массив, если какой-либо из элементов не установлен, установите их. Кажется, у этого будет куча проблем, но это мысль.
  4. Может быть, использовать какой-нибудь встроенный класс, предназначенный для этого?

Вышеупомянутое - это только первое, что пришло мне в голову, но я новичок в C++ и хотел бы иметь некоторое представление о нормальных или специальных решениях для маркировки массива как грязный.

Как я могу эффективно испачкать массив?

Чтобы показать пример кода, я покажу js, к которому я привык:

const numbers = [];
const clean = [];
let length = 1000;

let variable;
const setVariable(num) => {
  variable = num;
  for (let i = 0; i < length; i++) { clean[i] = false; }
}
setVariable(42);

let pos = 0;
while (true) {
  if (clean[pos] == false) {
    clean[pos] = true;
    numbers[pos] = someIntensiveMath(pos, variable);
  }
  doSomethingWithNumbers(numbers[pos]);
  pos++;
  if (pos >= length) pos = 0;
  // wait a bit;
}

в js вы также можете сделать

const setVariable(num) => {
  variable = num;
  numbers = [];
}
const isDirt = numbers[pos] === undefined;

С js последний, вероятно, будет быстрее из-за нативной реализации скрипта, но я не думаю, что в случае с компилируемыми языками. Я думаю, вы, ребята, делаете по-другому.

Непонятно, чего вы хотите достичь. Если весь массив зависит от одной переменной, разве недостаточно одного грязного флага? Если вы используете многопоточность, просто используйте блок мьютекса для чтения / записи переменной.

Srini 14.12.2018 19:43

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

Seph Reed 14.12.2018 19:48

так ты многопоточный?

Srini 14.12.2018 19:51

Это довольно общий вопрос, и часть «как я могу ... эффективно» является индикатором того, что это скорее вызовет самоуверенные ответы - почему бы не начать с вашего «простого» (неоптимизированного) решения, а затем попросить его улучшить? Как правило, это хороший подход - начать с простого и улучшить с этого момента ... и самый важный вопрос: уверены ли вы на 100%, что эта грязная пометка является самым большим узким местом в вашем приложении? Если нет (или вы в этом не уверены), то я бы порекомендовал сначала провести некоторые измерения!

codeling 14.12.2018 19:51

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

Seph Reed 14.12.2018 19:54

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

Dr t 14.12.2018 19:54

Обычным способом была бы карта. Если ключ существует, то значением является кэшированная запись. Очистить карту при изменении переменной.

stark 14.12.2018 19:57

Разве карта не была бы менее эффективной, чем массив, почти в любом случае? Или они оптимизированы для взаимозаменяемости?

Seph Reed 14.12.2018 20:03

@SephReed: в вопросе говорится: «У меня есть массив значений, которые рассчитываются на основе одной переменной». это означает, что они либо все грязные, либо нет. Но в комментарии говорится, что «одного флага недостаточно, чтобы определить, где массив чистый, а какой грязный». Можете прояснить вопрос? Без этого вопрос остается неясным.

Mooing Duck 14.12.2018 20:15

Думаю, мне следовало вместо этого сказать «грязные части массива». Я думал, что «грязная» парадигма, особенно применительно к массивам, была, возможно, немного более распространенной, чем она есть. В любом случае, я попытался добавить достаточно информации, чтобы было действительно очевидно, почему один флаг не работает.

Seph Reed 14.12.2018 20:21
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
10
164
1

Ответы 1

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

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

производительность массива по сравнению с картой

Неизвестно, привели ли изменения в современном коде к новому фактическому способу маркировки элементов или частей массива (или линейной коллекции элементов) как «грязных». Но, по крайней мере, в качестве ответа, самый простой способ - это иметь параллельный массив логических значений.

Кроме того, в зависимости от способа итерации «массива» может иметь смысл использовать вектор или карту. В случае любого из них форма загрязнения, вероятно, будет лучше всего реализована путем очистки карты или удаления векторных записей (??).

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

Для массивов, в отношении которых был задан этот вопрос, ответом могут быть параллельные массивы.

Другие вопросы по теме