- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
CompoundExpression*
CompoundExpression::newBinaryExpression(
BasicBinaryOperation::Type operation,
const Expression *x,
const Expression *y
) {
vector<Expression::const_pointer> params(2);
params[0] = x;
params[1] = y;
// integer power optimization
if (operation == BasicBinaryOperation::POWER) {
if (y->isNumber()) {
Number::const_pointer number_y = dynamic_cast<typeof number_y>(y);
if (number_y != NULL && number_y->isIntegerNumber()) {
IntegerNumber::const_pointer integer_y = dynamic_cast<typeof integer_y>(number_y);
if (integer_y != NULL) {
operation = BasicBinaryOperation::INT_POWER;
return new CompoundExpression(BinaryOperation::getOperation(operation), params);
}
}
}
}
// x^(y/n), where 'n' is odd integer
// transform to '(x^y)^(1/n)'
if (operation == BasicBinaryOperation::POWER) {
if (y->isCompoundExpression()) {
auto compoundExpressionY = dynamic_cast<CompoundExpression::const_pointer>(y);
if (compoundExpressionY != NULL && compoundExpressionY->operation->isBinary()) {
auto innerOperation = compoundExpressionY->operation;
auto binaryOperation = dynamic_cast<BinaryOperation const *>(innerOperation);
if (binaryOperation != NULL && binaryOperation->getType() == BasicBinaryOperation::DIVIDE) {
Expression::const_pointer numerator = compoundExpressionY->params[0];
Expression::const_pointer denominator = compoundExpressionY->params[1];
if (denominator->isNumber()) {
auto numberDenominator = dynamic_cast<Number::const_pointer>(denominator);
if (numberDenominator != NULL && numberDenominator->isIntegerNumber()) {
auto integerDenominator = dynamic_cast<IntegerNumber::const_pointer>(numberDenominator);
if (integerDenominator != NULL && (integerDenominator->intValue() % 2) != 0) {
auto base = CompoundExpression::newBinaryExpression(BasicBinaryOperation::POWER, x, numerator);
return CompoundExpression::newBinaryExpression(BasicBinaryOperation::NTH_ROOT, integerDenominator, base);
}
}
}
}
}
}
}
return new CompoundExpression(BinaryOperation::getOperation(operation), params);
}
Моё. Потребовалось воткнуть оптимизацию арифметического выражения некоторого вида. В результате родился вот такой костыль.
LispGovno 24.03.2013 16:13 # +6
Тут на лицо какая-то пессимизация.
Dummy00001 24.03.2013 20:26 # −2
давным давно я заглянул в сырцы GCC на предмет как там делаются оптимизации. после этого, то ГК сверху это не костыль - это ангельские крылья в сравнении.
что я хочу сказать. оптимизации основаны на эвристиках. любой набор эвристик будет выглядеть плохо. больше оптимизиций/эвристик - хуже будет смотреться.
guest 26.03.2013 15:35 # 0
> dynamic_cast
> dynamic_cast
> dynamic_cast
> dynamic_cast
> dynamic_cast
Соптимизировавший.
roman-kashitsyn 26.03.2013 15:45 # 0