Profiling#
In rbx, profiling is the process of measuring the execution time of solutions and coming up with time limits for the problem. Time limits are stored in limits profiles, which can be created and managed through the CLI or the TUI.
Why profile?#
Different judge systems (BOCA, Polygon, etc.) may run on different hardware with different performance characteristics. A time limit that works well on your local machine may be too tight or too generous on the actual judge. By creating separate profiles for each target system, you can fine-tune limits independently.
Even if you only target a single judge, profiling automates the tedious process of choosing a time limit that is generous enough for intended solutions but tight enough to reject slow ones.
Quick start#
# Estimate a time limit using the default formula (interactive)
rbx time
# Estimate automatically (no prompts)
rbx time --auto
# Create a profile for BOCA packaging
rbx time -p boca
# Write the estimated limits back into problem.rbx.yml
rbx time --integrate
The rbx time command#
The rbx time command (alias: rbx t) estimates a time limit for the problem by running all accepted
solutions and applying a formula to their timings.
How it works#
- Displays current profile -- If a profile already exists for the given name, its current limits are shown.
- Strategy selection -- You are prompted to choose how to define the time limit (unless
--autoor--strategyis used). - Solution execution -- For formula-based strategies, all accepted solutions are run against all testcases with no time limit enforced, so that the true execution times can be measured.
- Time report -- The fastest and slowest solution times are shown, along with per-language breakdowns if solutions in multiple languages exist.
- Formula evaluation -- The formula is applied to compute the estimated time limit.
- Per-language limits -- If solutions exist in multiple languages and their estimated limits differ, you are prompted to select which languages should have language-specific time limits.
- Profile persistence -- The result is written to
.limits/<profile>.yml.
Strategies#
When you run rbx time, you are prompted to choose a strategy:
| Strategy | Description |
|---|---|
| Estimate (recommended) | Runs all accepted solutions and applies the default formula to estimate the time limit. |
| Inherit from package | Creates a profile that inherits all limits directly from problem.rbx.yml. |
| Estimate with custom formula | Same as Estimate, but prompts you for a custom formula. |
| Custom time limit | Prompts you for an explicit time limit in milliseconds. |
You can skip the interactive prompt by using --strategy or --auto:
# Use the default formula without prompts
rbx time --auto
# Directly select a strategy
rbx time --strategy=estimate
rbx time --strategy=inherit
rbx time --strategy=custom
rbx time --strategy=estimate_custom
Flags#
| Flag | Short | Default | Description |
|---|---|---|---|
--profile |
-p |
local |
Name of the profile to create or update. |
--auto |
-a |
false |
Automatically estimate using the default formula (no prompts). |
--strategy |
-s |
(interactive) | Strategy to use: estimate, inherit, estimate_custom, or custom. |
--integrate |
-i |
false |
Write the profile's limits back into problem.rbx.yml (see Integrating profiles). |
--runs |
-r |
0 |
Number of runs per solution. 0 uses the environment default. |
--detailed |
-d |
false |
Print a detailed table view of per-testcase results. |
--check |
true |
Build outputs and run checker during estimation. | |
--validate |
true |
Validate inputs and outputs during estimation. |
Multiple runs#
By default, each solution is run once per testcase. If you want more stable timing measurements (e.g., to
reduce variance from system load), use --runs to run each solution multiple times:
The maximum time across all runs for each testcase is used as the timing for that testcase.
Time limit formulas#
Formula-based estimation is the recommended approach. A formula is a mathematical expression that takes the timing data from accepted solutions and produces a time limit.
Default formula#
The default formula is:
This means: take the maximum of 3x the fastest solution time and 1.5x the slowest solution time, then round up to the nearest multiple of 100 ms.
Variables#
| Variable | Description |
|---|---|
fastest |
Maximum time (in ms) of the fastest accepted solution across all testcases. |
slowest |
Maximum time (in ms) of the slowest accepted solution across all testcases. |
Note
fastest and slowest refer to the maximum time across testcases for the fastest/slowest solution,
not the fastest/slowest individual testcase. In other words, fastest is the worst-case time of the
best solution.
Functions#
| Function | Description |
|---|---|
step_up(value, step) |
Round value up to the nearest multiple of step. E.g., step_up(250, 100) = 300. |
step_down(value, step) |
Round value down to the nearest multiple of step. E.g., step_down(250, 100) = 200. |
step_closest(value, step) |
Round value to the closest multiple of step. |
max(a, b) |
Maximum of two values. |
min(a, b) |
Minimum of two values. |
int(x) |
Convert to integer. |
float(x) |
Convert to float. |
ceil(x) |
Ceiling function. |
floor(x) |
Floor function. |
abs(x) |
Absolute value. |
Standard math operators are also available: +, -, *, /, **, %.
Providing a custom formula#
You can provide a custom formula in three ways:
Set the default formula in your env.rbx.yml:
Read more in the Environment reference.
Formula examples#
# Conservative: 2x fastest, 1.5x slowest, round to 500ms
step_up(max(fastest * 2, slowest * 1.5), 500)
# Tight: 1.5x slowest, round to 100ms
step_up(slowest * 1.5, 100)
# Fixed multiplier on fastest
step_up(fastest * 4, 100)
Limits profiles#
Profiles are the mechanism rbx uses to store and manage time/memory limits independently of
the problem package itself. Each profile is a YAML file stored in the .limits/ directory of your
problem.
File structure#
my-problem/
├── problem.rbx.yml
├── .limits/
│ ├── local.yml # Default profile
│ ├── boca.yml # Profile for BOCA packaging
│ └── polygon.yml # Profile for Polygon packaging
Profile schema#
A profile file follows the LimitsProfile schema:
# .limits/local.yml
# Inherit all limits from problem.rbx.yml instead of specifying them here.
# When true, the fields below are ignored.
inheritFromPackage: false
# Global limits
timeLimit: 2000 # Time limit in milliseconds
memoryLimit: 256 # Memory limit in MB
outputLimit: 65536 # Output limit in KB
# Per-language overrides
modifiers:
py:
time: 6000 # Python gets a higher time limit (ms)
java:
timeMultiplier: 2.0 # Java gets 2x the base time limit
# The formula that was used to estimate the time limit (informational)
formula: "step_up(max(fastest * 3, slowest * 1.5), 100)"
Per-language modifiers#
The modifiers section allows you to override limits for specific languages. This is useful
when your problem accepts solutions in multiple languages with very different performance characteristics.
| Field | Description |
|---|---|
time |
Override the time limit for this language (in ms). Replaces the global timeLimit. |
timeMultiplier |
Multiply the effective time limit by this factor. Applied after time if both are set. |
memory |
Override the memory limit for this language (in MB). |
The effective time limit for a language is computed as:
- Start with the global
timeLimit. - If the language has a
timemodifier, use that instead. - If the language has a
timeMultiplier, multiply the result by it.
Tip
When rbx time detects that your accepted solutions are written in multiple languages with different
performance characteristics, it will prompt you to set per-language time limits automatically.
The local profile#
By default, rbx time writes to a profile named local. This profile is used when you run
solutions with rbx run without specifying a profile.
Using profiles when running solutions#
You can tell rbx to use a specific limits profile when running solutions with the global --profile flag:
This applies the limits from the specified profile instead of the package defaults.
Profiles and packaging#
When you package a problem, rbx automatically uses the profile that matches the packager name.
For example, the BOCA packager looks for a profile named boca:
Warning
The BOCA packager requires a profile named boca to exist. If it doesn't, the packager will fail
and ask you to run rbx time -p boca first.
Inheriting from the package#
If you want a profile to simply mirror the limits defined in problem.rbx.yml, you can create
an inheriting profile:
This creates a .limits/polygon.yml with inheritFromPackage: true. The profile will always
reflect whatever limits are set in problem.rbx.yml.
Integrating profiles into the package#
If you've estimated limits in a profile and want to write them back into problem.rbx.yml
(for example, to make them the new defaults), use the --integrate flag:
This copies timeLimit, memoryLimit, outputLimit, and any modifiers from the profile
into your problem.rbx.yml. It is useful when you've fine-tuned limits in a profile and want
to persist them as the package defaults.
Editing profiles in the TUI#
You can also create and edit limits profiles visually using the rbx TUI:
Select "Edit limits profiles" from the main menu to open the limits editor. The editor provides:
- Profile sidebar -- Browse and select from all existing profiles in
.limits/. - Create new profile -- Type a name and press Enter to create a new profile.
- Inherit toggle -- Switch between inheriting from the package or setting custom limits.
- Global limits -- Edit
timeLimitandmemoryLimitdirectly. - Per-language modifiers -- Add or edit
time,timeMultiplier, andmemoryoverrides for specific languages. - Save (Ctrl+S) -- Write changes to disk.
- Delete (d twice) -- Delete the selected profile.
Tip
The TUI is especially handy for quickly tweaking per-language modifiers after an initial
rbx time estimation.
Manually editing profiles#
Since profiles are plain YAML files in the .limits/ directory, you can also edit them directly
with any text editor. The schema is available at LimitsProfile.
You can add the following YAML language server directive at the top of your profile file for editor autocompletion and validation:
Environment variable override#
You can globally scale all time limits by setting the RBX_TIME_MULTIPLIER environment variable:
This multiplies all effective time limits by the given factor, which can be useful for running on slower hardware without changing any profile.