def calc_controllers_for_workload(num_streams, heavy_operations_per_second, light_operations_per_second, performance_profile):
    """
    Given the Controller throughput for the different operation types provided in the performance profile, we derive the
    necessary number of Controllers to handle the target metadata workload.
    :param num_streams: Expected number of Streams in the system.
    :param heavy_operations_per_second: Heavy (Stream, Transaction) operations per second.
    :param light_operations_per_second: Light (Scope, Ping, Endpoints, Segments) operations per second.
    :param performance_profile:  Class containing the performance of the Controller in the target environment.
    :return: Number of Controller instances to absorb the target metadata workload.
    """
    return int(max(num_streams / performance_profile.max_streams_per_controller + 1,
               heavy_operations_per_second / performance_profile.controller_max_heavy_operations_per_second + 1,
               light_operations_per_second / performance_profile.controller_max_light_operations_per_second + 1))