0

Ich arbeite an einer stündlichen Hotelbuchungsanwendung. Es gibt eine peak_seasons Tabelle, die start_date und end_date speichert. Peak_Seasons sind vordefinierte Daten für das aktuelle Jahr in meiner Anwendung. Wenn ein Kunde eine Buchung für die ausgewählten Stunden vornimmt, muss ich überprüfen, ob eine dieser Stunden zur Hauptsaison gehört, so dass ich für diese Stunden einen anderen Tarif anwenden kann.Was ist der optimale Weg zu finden, ob eine bestimmte Stunde zur Hauptsaison gehört

Dieser Vorgang ist so häufig, dass ich ihn optimieren möchte. Brauche Ideen. Mein aktueller Pseudo-Code ist dies:

def calculate_price(customer_start_time, customer_end_time) 
    price = 0 
    (customer_start_time.to_i...customer_end_time.to_i).step(1.hour) do |hour| 
    //now check if this hour belongs to peak season over here 
    if peak_seasons?(hour) 
     price += price + peak_season_price 
    else 
     price += price + standard_price 
    end 
    return price 
end 

//peak_seasons? somewhere 
def peak_seasons?(hour) 
    PeakSeason.where("start_date <= ? and end_date >= ?", hour.to_date, hour.to_date).any? 
end 

Ich denke, das nicht effizient Code ist, wenn hundreads von Kunden den Preis für ausgewählte Stunden überprüft, dann Daten von DB für jede Stunde ausgewählt holen wird. Wie man es optimiert?

+0

sind 'customer_start_time, customer_end_time' DateTime? – neydroid

+0

Sie könnten 'BETWEEN' für die Abfrage verwenden,'? BETWEEN start_date UND end_date'. Anstatt nach jeder Stunde abzufragen, können Sie nach den vier möglichen Intervallkreuzungen fragen, die höchstens 4 Abfragen sind. – sschmeck

+0

@neydroid Ja, 'customer_start_time, customer_end_time' sind DateTime. @sschmeck, danke, ja, ich kann Abfragen reduzieren, indem ich nach Intervallen und nicht nach Stunden suche. Gibt es einen Weg, auf dem wir die Hauptsaison nur einmal abholen und speichern müssen? wird es besser sein? –

Antwort

0

Sie könnten versuchen, alle PeakSeason Datensätze für ein bestimmtes Intervall auf einmal auszuwählen.

def all_peak_seasons(customer_start_time, customer_end_time) 
    PeakSeason.where(":start_time BETWEEN start_date AND end_date OR "\ 
        ":end_time BETWEEN start_date AND end_date OR "\ 
        "start_date BETWEEN :start_time AND :end_time", 
        {start_time: customer_start_time, end_time: customer_end_time}) 
end 
1

Sie könnten eine Super effiziente Lösung erstellen, indem Sie das Caching alle PeakSeason Daten und unter Verwendung eines Interval tree (siehe auch this answer) für die Berechnung. Aber Sie sagen "Ich denke, das ist nicht effizient" - ehrlich gesagt, rate ich gegen diese Art der Optimierung, es sei denn, Sie wissen wirklich, ist ein Leistungsproblem.

Verwandte Themen