tpaviot / ProcessScheduler

A Python package for automatic and optimized resource scheduling
https://processscheduler.github.io/
GNU General Public License v3.0
59 stars 17 forks source link

Performance of Workload resource constraint #49

Closed dreinon closed 3 years ago

dreinon commented 3 years ago

I have a couple workload constraints (around 20) to be added to my problem, but creating them takes a while. Is this performance normal or might I be missing something? Elapsed time: 0.5467 seconds Elapsed time: 1.1201 seconds Elapsed time: 1.9432 seconds Elapsed time: 2.9160 seconds Elapsed time: 1.8898 seconds Elapsed time: 3.1027 seconds Elapsed time: 3.0702 seconds Elapsed time: 1.2920 seconds Elapsed time: 1.0977 seconds Elapsed time: 1.9146 seconds Elapsed time: 1.1236 seconds Elapsed time: 1.9814 seconds Elapsed time: 3.0074 seconds Elapsed time: 1.3524 seconds Elapsed time: 2.1051 seconds Elapsed time: 1.3095 seconds Elapsed time: 2.1646 seconds Elapsed time: 3.3746 seconds Elapsed time: 1.2358 seconds Elapsed time: 1.4477 seconds

tpaviot commented 3 years ago

I did not test use-cases that involve many WorkLoad constraints. Can you share the smallest example that reproduces the issue?

dreinon commented 3 years ago
import processscheduler as ps
from codetiming import Timer

HORIZON = 60
MAX_TASKS_PER_PERIOD = 2
MAX_TASKS_IN_PROBLEM = 4
NB_WORKERS = 10
NB_TASKS_PER_WORKER = 5
PERIODS = [(10*i, 10*(i+1)) for i in range(int(HORIZON/10))]  # Periods of 10 slots from 0 to horizon

# Create problem and initialize constraints
pb = ps.SchedulingProblem(name='workload_performance_example', horizon=HORIZON)
constraints = []

# Create resources and assign tasks
general_worker = ps.Worker('general')
workers = []
for i in range(NB_WORKERS):
    name = f'worker_{i+1}'
    worker = ps.Worker(name)

    # Create tasks and assign resources
    tasks = []
    for j in range(NB_TASKS_PER_WORKER):
        tasks.append(ps.FixedDurationTask(f'{name}__{j:02d}', duration=1, optional=True))
        tasks[-1].add_required_resources([general_worker, worker])

    workers.append({
        'name': name,
        'worker': worker,
        'tasks': tasks
    })

workload = {period: MAX_TASKS_PER_PERIOD for period in PERIODS}
workload[(0, HORIZON)] = MAX_TASKS_IN_PROBLEM
for worker in workers:
    t = Timer()
    t.start()
    constraints.append(ps.WorkLoad(worker['worker'], workload, kind='max'))
    t.stop()

# Add constraints, define objective and solve problem
pb.add_constraints(constraints)
pb.add_objective_resource_utilization(general_worker)
solution = ps.SchedulingSolver(pb).solve()
dreinon commented 3 years ago

Having updated and installed my local repo, as mentioned in #43, performance keeps the same (around 4 sec. per constraint).

dreinon commented 3 years ago

Don't you get the same performance, @tpaviot?

tpaviot commented 3 years ago

Yes I have, issue confirmed. Regarding issue #43, I did not change anything to the WorkLoad constraint, so it's normal there's no difference

dreinon commented 3 years ago

Oh okay, I thought you mentioned performance because of this issue.

tpaviot commented 3 years ago

Bottleneck identified here https://github.com/tpaviot/ProcessScheduler/blob/master/processscheduler/base.py#L80