Skip to content

Commit f889672

Browse files
committed
simplify comparison of programs
1 parent 7ce427e commit f889672

File tree

4 files changed

+33
-48
lines changed

4 files changed

+33
-48
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ To install or update LODA, please follow the [installation instructions](https:/
66

77
* Fix handling of protected programs
88

9+
### Enhancements
10+
11+
* Simplify comparison of programs (better/faster)
12+
913
# v22.6.27
1014

1115
### Bugfixes

src/finder.cpp

Lines changed: 23 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -173,25 +173,15 @@ std::pair<std::string, Program> Finder::checkProgramDefault(
173173
}
174174

175175
// update result with minimized program
176+
result.second = program;
177+
176178
if (is_new) {
177179
// no additional checks needed for new programs
178180
result.first = "First";
179-
result.second = program;
180181
} else {
181182
// now we are in the "update" case
182-
// first: compare minimized program with original program
183-
steps_t optimized_steps;
184-
auto compare =
185-
isOptimizedBetter(result.second, program, optimized_steps, seq);
186-
if (!compare.first.empty()) {
187-
// use minimized version
188-
result.second = program;
189-
optimized_steps = compare.second;
190-
}
191-
// second: compare (minimized) program with existing programs
192-
compare =
193-
isOptimizedBetter(existing, result.second, optimized_steps, seq.id);
194-
result.first = compare.first;
183+
// compare (minimized) program with existing programs
184+
result.first = isOptimizedBetter(existing, result.second, seq.id);
195185
}
196186

197187
// clear result program if it's no good
@@ -259,23 +249,22 @@ size_t getBadOpsCount(const Program &p) {
259249
return num_ops;
260250
}
261251

262-
std::pair<std::string, steps_t> Finder::isOptimizedBetter(
263-
Program existing, Program optimized, steps_t optimized_steps,
264-
const OeisSequence &seq) {
265-
std::pair<std::string, steps_t> result;
252+
std::string Finder::isOptimizedBetter(Program existing, Program optimized,
253+
const OeisSequence &seq) {
254+
static const std::string not_better;
266255

267256
// remove nops...
268257
optimizer.removeNops(existing);
269258
optimizer.removeNops(optimized);
270259

271-
// we want at least one operation (avoid empty program for A000004
260+
// we want at least one operation (avoid empty program for A000004)
272261
if (optimized.ops.empty()) {
273-
return result;
262+
return not_better;
274263
}
275264

276265
// if the programs are the same, no need to evaluate them
277266
if (optimized == existing) {
278-
return result;
267+
return not_better;
279268
}
280269

281270
// check if the optimized program supports IE
@@ -285,18 +274,17 @@ std::pair<std::string, steps_t> Finder::isOptimizedBetter(
285274
const bool inc_eval_existing = evaluator.supportsIncEval(existing);
286275
const bool inc_eval_optimized = evaluator.supportsIncEval(optimized);
287276
if (inc_eval_optimized && !inc_eval_existing) {
288-
result.first = "Faster (IE)";
289-
return result;
277+
return "Faster (IE)";
290278
} else if (!inc_eval_optimized && inc_eval_existing) {
291-
return result; // worse
279+
return not_better; // worse
292280
}
293281
}
294282

295283
// check if there are loops with contant number of iterations involved
296284
if (ProgramUtil::hasLoopWithConstantNumIterations(optimized)) {
297285
// independently of the existing program, we stop here because
298286
// otherwise it yields fake optimization of constant loops
299-
return result;
287+
return not_better;
300288
}
301289

302290
// get extended sequence
@@ -306,51 +294,45 @@ std::pair<std::string, steps_t> Finder::isOptimizedBetter(
306294
}
307295

308296
// evaluate optimized program for fixed number of terms
309-
static const int64_t num_terms = 4000; // magic number
297+
static const int64_t num_terms = OeisSequence::EXTENDED_SEQ_LENGTH;
310298
Sequence tmp;
311-
if (optimized_steps.runs == 0) { // eval optimized only if needed!
312-
optimized_steps = evaluator.eval(optimized, tmp, num_terms, false);
313-
}
314-
result.second = optimized_steps;
299+
auto optimized_steps = evaluator.eval(optimized, tmp, num_terms, false);
315300

316301
// check if the first decreasing/non-increasing term is beyond the known
317302
// sequence terms => fake "better" program
318303
const int64_t s = terms.size();
319304
if (tmp.get_first_delta_lt(Number::ZERO) >= s || // decreasing
320305
tmp.get_first_delta_lt(Number::ONE) >= s) { // non-increasing
321-
return result; // => fake "better" program
306+
return not_better; // => fake "better" program
322307
}
323308

324309
// evaluate existing program for same number of terms
325310
const auto existing_steps = evaluator.eval(existing, tmp, num_terms, false);
326311

327312
// compare number of successfully computed terms
328313
if (optimized_steps.runs > existing_steps.runs) {
329-
result.first = "Better";
330-
return result;
314+
return "Better";
331315
} else if (optimized_steps.runs < existing_steps.runs) {
332-
return result; // worse
316+
return not_better; // worse
333317
}
334318

335319
// compare number of "bad" operations
336320
auto optimized_bad_count = getBadOpsCount(optimized);
337321
auto existing_bad_count = getBadOpsCount(existing);
338322
if (optimized_bad_count < existing_bad_count) {
339-
result.first = "Simpler";
340-
return result;
323+
return "Simpler";
341324
} else if (optimized_bad_count > existing_bad_count) {
342-
return result; // worse
325+
return not_better; // worse
343326
}
344327

345328
// ...and compare number of execution cycles
346329
if (optimized_steps.total < existing_steps.total) {
347-
result.first = "Faster";
348-
return result;
330+
return "Faster";
349331
} else if (optimized_steps.total > existing_steps.total) {
350-
return result; // worse
332+
return not_better; // worse
351333
}
352334

353-
return result; // not better or worse => no change
335+
return not_better; // not better or worse => no change
354336
}
355337

356338
void Finder::notifyInvalidMatch(size_t id) {

src/include/finder.hpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,8 @@ class Finder {
5353

5454
void notifyInvalidMatch(size_t id);
5555

56-
std::pair<std::string, steps_t> isOptimizedBetter(Program existing,
57-
Program optimized,
58-
steps_t optimized_steps,
59-
const OeisSequence &seq);
56+
std::string isOptimizedBetter(Program existing, Program optimized,
57+
const OeisSequence &seq);
6058

6159
void notifyMinimizerProblem(const Program &p, const std::string &id);
6260

src/util.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -381,9 +381,10 @@ bool AdaptiveScheduler::isTargetReached() {
381381
// check every 500ms
382382
speed = (500 * total_checks) / std::max<int64_t>(milliseconds, 1);
383383
next_check += std::min<int64_t>(std::max<int64_t>(speed, 1), 1000);
384-
// Log::get().info("next check " + std::to_string(next_check) + " speed " +
385-
// std::to_string(speed) + " target " +
386-
// std::to_string(target_milliseconds));
384+
// Log::get().info(
385+
// "Next check " + std::to_string(next_check - current_checks) +
386+
// "; Speed: " + std::to_string(speed) +
387+
// "; Target: " + std::to_string(target_milliseconds / 1000) + "s");
387388
}
388389
return false;
389390
}

0 commit comments

Comments
 (0)