Беру CCleaner, чищу реестр.Руки оторвать, и выгнать из профессии.
Дефрагментирую дискОтправить лечиться от идиотизма.
Как вы улучшаете «скорость» работы компьютера?Мониторим нагрузку, находим узкие места, устраняем. Т.е добавляем памяти, меняем диск на более быстрый, или компьютер на более производительный.
Box
в целом не должен уметь что-то кроме хранения фигур. Как правильно заметил vgbege - из задачи не следует что в дальнейшем вариантов подсчёта каких-то метрик по фигурам с Box'е не станет больше, так что в первую очередь я бы выносил отдельно калькулятор. Также у вас нет обобщающего интерфейса для IArea
и IShape
из-за чего и возникает путаница в addShape
. /**
* Основной интерфейс для всех фигур которые можно хранить в Box'е
*/
interface IFigure
{
}
/**
* Интерфейс для фигур которые могут обладать площадью
*/
interface IArea extends IFigure
{
public function getArea(): float;
}
/**
* Интерфейс для фигур которые могут обладать цветом заливки
*/
interface IFillColor
{
public function setFillColor(string $color): self;
public function getFillColor(): string;
}
/**
* Обобщённый интерфейс для фигур, обладающих и цветом и площадью
* По факту, думаю, он не имеет смысла, но нужен по условию задачи
*/
interface IShape extends IArea, IFillColor
{
}
/**
* Коробка для хранения фигур
*/
class Box
{
/**
* @var IFigure[]
*/
private $figures = [];
/**
* @param IFigure[] $figures
*/
public function __construct(array $figures = [])
{
// Добавляем полученные через конструктор фигуры в объект
// Используем addFigure() чтобы проконтролировать корректность типов
array_walk($figures, [$this, 'addFigure']);
}
/**
* @param IFigure $figure
* @return $this
*/
public function addFigure(IFigure $figure): self
{
$this->figures[] = $figure;
return $this;
}
/**
* @param IFigure $figure
* @return bool
*/
public function hasFigure(IFigure $figure): bool
{
return in_array($figure, $this->figures, true);
}
/**
* @param IFigure $figure
* @return $this
*/
public function removeFigure(IFigure $figure): self
{
$this->figures = array_filter($this->figures, static function (IFigure $f) use ($figure) {
return $f !== $figure;
});
return $this;
}
/**
* @return IFigure[]
*/
public function getFigures(): array
{
return $this->figures;
}
}
/**
* Интерфейс для калькуляторов фигур в Box'ах
*/
interface IFigureCalculator
{
/**
* @param Box $box
* @param mixed ...$args
* @return mixed
*/
public function calculate(Box $box, ...$args);
}
/**
* Пример калькулятора
*/
class AreaCalculator implements IFigureCalculator
{
public function calculate(Box $box, ...$args): float
{
// Получаем список фигур которые обладают площадью
$figures = array_filter($box->getFigures(), static function (IFigure $figure) {
return $figure instanceof IArea;
});
// Получаем цвет из дополнительных аргументов калькулятора
$color = array_shift($args);
if ($color) {
// У нас задан цвет, фильтруем фигуры по цвету
$figures = array_filter($figures, static function (IFigure $figure) use ($color) {
return $figure instanceof IFillColor && $figure->getFillColor() === $color;
});
}
// Подсчитываем суммарную площадь
return array_reduce($figures, static function (float $area, IArea $figure) {
return $area + $figure->getArea();
}, 0);
}
}
public function calculate(IFigureCalculator $calculator, ...$args)
/**
* Hold Your Horses!
* Promise-based dispatcher that respects frequency limits.
* It queues requests so that no more than N are processed within 1 second.
* Those can go in parallel.
*
* Instantiate the new HH with options, specifying time limit.
* Method .add(function) adds a new job to the queue.
* Argument function should return Promise object that starts to process only after the function is called.
* @return Object Promise.
*/
function HorsesHolder(options) {
options = options || {};
this.rps = options.rps || 3; // requests per second
this.parallel = options.parallel || this.rps; // max parallel running jobs
this.times = []; // -1: slot is busy, 0: slot is free, positive timestamp - time slot's job has finished
for (let i=0; i<this.rps; i++) this.times.push(0); // [0, 0, 0] initially
this.queue = [];
this.inprogress = [];
this.debug = !!options.debug;
this.debug && console.log("%s ms: [HH] initialized", this.ts());
}
HorsesHolder.prototype.add = function(promiseMaker) {
var self = this;
return new Promise(function(resolve, reject) {
self.queue.push({
resolve: resolve,
reject: reject,
promiseMaker: promiseMaker,
});
self._ping();
});
};
// Decide: work or wait
HorsesHolder.prototype._ping = function() {
if (this.queue.length === 0) {
this.debug && console.log("%s ms: [ping] queue is empty", this.ts());
return;
}
const best = this._bestTime();
if (best === -1) {
this.debug && console.log("%s ms: [ping] cannot go: %s", this.ts(), JSON.stringify(this.times));
return;
}
const index = this.times.indexOf(best);
this.debug && console.info("%s ms: [ping] exec now at index %d", this.ts(), index);
this._execute(index);
}
/**
* Out of current times[] finds the best to occupy, if possible;
* otherwise -1
*/
HorsesHolder.prototype._bestTime = function() {
let best = -1;
for (let i=0; i<this.rps; i++) {
const time = this.times[i];
if (time === 0) return 0; // can go now - nothing better!
if (time < 0) continue; // previous not finished yet
if (this.ts() < time + 1000) continue; // not yet
if (best === -1) best = time;
else best = Math.min(best, time);
}
return best;
}
HorsesHolder.prototype.ts = function() {
return (new Date()).getTime();
}
HorsesHolder.prototype._execute = function(index) {
this.times[index] = -1; // mark busy
const job = this.queue.shift();
this.inprogress.push(job);
const self = this;
job.promiseMaker()
.then(function(r) {
self.debug && console.info("%s ms: [HH] Job done at index %d", self.ts(), index);
job.resolve(r);
})
.catch(function(err){
self.debug && console.error("%s ms: [HH err] Error at index %d: %s", self.ts(), index, err.toString());
job.reject(err);
})
.finally(function(){
self.inprogress.splice( self.inprogress.indexOf(job), 1);
self.times[index] = self.ts();
setTimeout(() => self._ping(), 1000);
});
}
export default HorsesHolder;
/*global VK*/
/**
* Function returns Promise for each VK API call.
* Respects the 3 call per second limit.
*
* by Sergei Sokolov <hello@sergeisokolov.com> 2019.
*/
import HorsesHolder from '@/utils/horsesholder';
const debug = true;
const HH = new HorsesHolder({ debug });
export default function asyncVK(methodName, data) {
return HH.add(() => {
data = data || {};
if (!data.v) data.v = 5.92; // VK API version https://vk.com/dev/versions
return new Promise((res, rej) => {
VK.Api.call(
methodName,
data,
r => {
if (r.error) {
debug && console.error("[asyncvk] VK API call error:", r.error);
}
if (r.response) {
res(r.response);
} else if (r.error) {
rej(r.error);
} else {
debug && console.error("[asyncvk] VK API bad response:", r);
rej(r);
}
}
)
});
});
}
тихий серверный шкаф
Изучаю PHP рекомендуют читать чужой код.
async function ITPIsActive() {
if (document.hasStorageAccess && document.requestStorageAccess) {
const access = await new Promise(function(res, rej) {
document.hasStorageAccess().then(res, rej).catch(rej);
});
return access;
} else {
return false;
}
}
data = [........]
render() {
return (
<>
{ data.map(x => <MyComponent prop1={x.prop1} prop2={x.prop2} />) }
</>
)
}
data = [........]
render() {
const components = []
for(let i = 0; i < data.length; i++) {
const x = data[i]
components.push(<MyComponent prop1={x.prop1} prop2={x.prop2} />)
}
return (
<>
{ components }
</>
)
}