Avoid the performance/memory overheads of "clone on modify" of $args (#1884)
* Avoid the performance/memory overheads of "clone on modify" of $args when building the condition set/database for AVERAGEIFS(), MAXIFS() and MINIFS() * Avoid the performance/memory overheads of "clone on modify" of $args when building the condition set/database for COUNTIFS()
This commit is contained in:
parent
80a20fc991
commit
761c84a946
|
|
@ -67,8 +67,8 @@ class Conditional
|
|||
return self::AVERAGEIF($args[2], $args[1], $args[0]);
|
||||
}
|
||||
|
||||
$conditions = self::buildConditionSet(...$args);
|
||||
$database = self::buildDatabase(...$args);
|
||||
$conditions = self::buildConditionSetForRange(...$args);
|
||||
$database = self::buildDatabaseWithRange(...$args);
|
||||
|
||||
return DAverage::evaluate($database, self::VALUE_COLUMN_NAME, $conditions);
|
||||
}
|
||||
|
|
@ -122,19 +122,8 @@ class Conditional
|
|||
return self::COUNTIF(...$args);
|
||||
}
|
||||
|
||||
$conditions = $database = [];
|
||||
$pairCount = 1;
|
||||
while (count($args) > 0) {
|
||||
$conditions[] = array_merge([sprintf(self::CONDITIONAL_COLUMN_NAME, $pairCount)], [array_pop($args)]);
|
||||
$database[] = array_merge(
|
||||
[sprintf(self::CONDITIONAL_COLUMN_NAME, $pairCount)],
|
||||
Functions::flattenArray(array_pop($args))
|
||||
);
|
||||
++$pairCount;
|
||||
}
|
||||
|
||||
$conditions = array_map(null, ...$conditions);
|
||||
$database = array_map(null, ...$database);
|
||||
$database = self::buildDatabase(...$args);
|
||||
$conditions = self::buildConditionSet(...$args);
|
||||
|
||||
return DCount::evaluate($database, null, $conditions);
|
||||
}
|
||||
|
|
@ -157,8 +146,8 @@ class Conditional
|
|||
return 0.0;
|
||||
}
|
||||
|
||||
$conditions = self::buildConditionSet(...$args);
|
||||
$database = self::buildDatabase(...$args);
|
||||
$conditions = self::buildConditionSetForRange(...$args);
|
||||
$database = self::buildDatabaseWithRange(...$args);
|
||||
|
||||
return DMax::evaluate($database, self::VALUE_COLUMN_NAME, $conditions);
|
||||
}
|
||||
|
|
@ -181,23 +170,22 @@ class Conditional
|
|||
return 0.0;
|
||||
}
|
||||
|
||||
$conditions = self::buildConditionSet(...$args);
|
||||
$database = self::buildDatabase(...$args);
|
||||
$conditions = self::buildConditionSetForRange(...$args);
|
||||
$database = self::buildDatabaseWithRange(...$args);
|
||||
|
||||
return DMin::evaluate($database, self::VALUE_COLUMN_NAME, $conditions);
|
||||
}
|
||||
|
||||
private static function buildConditionSet(...$args): array
|
||||
{
|
||||
array_shift($args);
|
||||
$conditions = self::buildConditions(1, ...$args);
|
||||
|
||||
$conditions = [];
|
||||
$pairCount = 1;
|
||||
while (count($args) > 0) {
|
||||
$conditions[] = array_merge([sprintf(self::CONDITIONAL_COLUMN_NAME, $pairCount)], [array_pop($args)]);
|
||||
array_pop($args);
|
||||
++$pairCount;
|
||||
}
|
||||
return array_map(null, ...$conditions);
|
||||
}
|
||||
|
||||
private static function buildConditionSetForRange(...$args): array
|
||||
{
|
||||
$conditions = self::buildConditions(2, ...$args);
|
||||
|
||||
if (count($conditions) === 1) {
|
||||
return array_map(
|
||||
|
|
@ -211,20 +199,46 @@ class Conditional
|
|||
return array_map(null, ...$conditions);
|
||||
}
|
||||
|
||||
private static function buildConditions(int $startOffset, ...$args): array
|
||||
{
|
||||
$conditions = [];
|
||||
|
||||
$pairCount = 1;
|
||||
$argumentCount = count($args);
|
||||
for ($argument = $startOffset; $argument < $argumentCount; $argument += 2) {
|
||||
$conditions[] = array_merge([sprintf(self::CONDITIONAL_COLUMN_NAME, $pairCount)], [$args[$argument]]);
|
||||
++$pairCount;
|
||||
}
|
||||
|
||||
return $conditions;
|
||||
}
|
||||
|
||||
private static function buildDatabase(...$args): array
|
||||
{
|
||||
$database = [];
|
||||
|
||||
return self::buildDataSet(0, $database, ...$args);
|
||||
}
|
||||
|
||||
private static function buildDatabaseWithRange(...$args): array
|
||||
{
|
||||
$database = [];
|
||||
$database[] = array_merge(
|
||||
[self::VALUE_COLUMN_NAME],
|
||||
Functions::flattenArray(array_shift($args))
|
||||
Functions::flattenArray($args[0])
|
||||
);
|
||||
|
||||
return self::buildDataSet(1, $database, ...$args);
|
||||
}
|
||||
|
||||
private static function buildDataSet(int $startOffset, array $database, ...$args): array
|
||||
{
|
||||
$pairCount = 1;
|
||||
while (count($args) > 0) {
|
||||
array_pop($args);
|
||||
$argumentCount = count($args);
|
||||
for ($argument = $startOffset; $argument < $argumentCount; $argument += 2) {
|
||||
$database[] = array_merge(
|
||||
[sprintf(self::CONDITIONAL_COLUMN_NAME, $pairCount)],
|
||||
Functions::flattenArray(array_pop($args))
|
||||
Functions::flattenArray($args[$argument])
|
||||
);
|
||||
++$pairCount;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue