Обновлено: видимо, я неправильно задал этот вопрос. Перед тем, как проголосовать за закрытие, позвольте мне узнать, какой вопрос отсутствует. Обещаю, это не вопрос без ответа. Вы всегда можете вернуться и проголосовать, чтобы закрыть его позже.
В настоящее время я работаю на C++, но думаю, что этот вопрос относится к большинству компилируемых языков.
В моем проекте у меня есть массив значений, которые рассчитываются индивидуально, по одному, как можно позже на основе одной переменной. Эти значения не вычисляются сразу, они вычисляются тогда и только тогда, когда это необходимо. Как это обычно бывает при использовании «грязного», цель состоит в том, чтобы пометить определенные вещи как нуждающиеся в обновлении, без предварительного обновления. Эти значения циклически меняются снова и снова, поэтому я хотел бы кэшировать вычисления, если это возможно. Всякий раз, когда изменяется одна переменная, все значения должны быть помечены как грязные, чтобы цикл знал, что нужно пересчитать, прежде чем сохранять и двигаться дальше.
Я могу придумать несколько способов добиться этого, но не уверен, какой из них наиболее эффективен:
Вышеупомянутое - это только первое, что пришло мне в голову, но я новичок в 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 последний, вероятно, будет быстрее из-за нативной реализации скрипта, но я не думаю, что в случае с компилируемыми языками. Я думаю, вы, ребята, делаете по-другому.
Прошу прощения за то, что не совсем ясно. Переменная может меняться много раз в течение цикла, поэтому одного флага будет недостаточно, чтобы определить, где массив чистый, а какой грязный. Длина массива никогда не меняется.
так ты многопоточный?
Это довольно общий вопрос, и часть «как я могу ... эффективно» является индикатором того, что это скорее вызовет самоуверенные ответы - почему бы не начать с вашего «простого» (неоптимизированного) решения, а затем попросить его улучшить? Как правило, это хороший подход - начать с простого и улучшить с этого момента ... и самый важный вопрос: уверены ли вы на 100%, что эта грязная пометка является самым большим узким местом в вашем приложении? Если нет (или вы в этом не уверены), то я бы порекомендовал сначала провести некоторые измерения!
Я согласен, что это потенциально очень ситуативно, но я подхожу к этому с широкой точки зрения, даже не зная, как это сделать нормальный. Это не вопрос, основанный на очень конкретном случае, а в широком смысле. Добавлю свою версию.
почему бы вам не сделать это со структурами? Если переменная-член должна быть изменена, создайте новый экземпляр структуры и добавьте изменения ...
Обычным способом была бы карта. Если ключ существует, то значением является кэшированная запись. Очистить карту при изменении переменной.
Разве карта не была бы менее эффективной, чем массив, почти в любом случае? Или они оптимизированы для взаимозаменяемости?
@SephReed: в вопросе говорится: «У меня есть массив значений, которые рассчитываются на основе одной переменной». это означает, что они либо все грязные, либо нет. Но в комментарии говорится, что «одного флага недостаточно, чтобы определить, где массив чистый, а какой грязный». Можете прояснить вопрос? Без этого вопрос остается неясным.
Думаю, мне следовало вместо этого сказать «грязные части массива». Я думал, что «грязная» парадигма, особенно применительно к массивам, была, возможно, немного более распространенной, чем она есть. В любом случае, я попытался добавить достаточно информации, чтобы было действительно очевидно, почему один флаг не работает.





В другом месте я обнаружил, что типичный способ пометить записи массива «грязными» - это иметь параллельный массив логических значений.
@stark упомянул в комментариях, что идея использования карты и сравнение скорости двух кажутся довольно приличными, но в следующем ответе было рекомендовано использовать массив для индексированных элементов.
производительность массива по сравнению с картой
Неизвестно, привели ли изменения в современном коде к новому фактическому способу маркировки элементов или частей массива (или линейной коллекции элементов) как «грязных». Но, по крайней мере, в качестве ответа, самый простой способ - это иметь параллельный массив логических значений.
Кроме того, в зависимости от способа итерации «массива» может иметь смысл использовать вектор или карту. В случае любого из них форма загрязнения, вероятно, будет лучше всего реализована путем очистки карты или удаления векторных записей (??).
Итак, чтобы дать свой лучший ответ, казалось бы, сначала нужно найти метод хранения, который лучше всего соответствует их потребностям, а затем использовать тот, который наиболее подходит для этого.
Для массивов, в отношении которых был задан этот вопрос, ответом могут быть параллельные массивы.
Непонятно, чего вы хотите достичь. Если весь массив зависит от одной переменной, разве недостаточно одного грязного флага? Если вы используете многопоточность, просто используйте блок мьютекса для чтения / записи переменной.