Created
July 24, 2015 14:16
-
-
Save ubourdon/f11976e00941d73b32d4 to your computer and use it in GitHub Desktop.
extract parts of algo in function produce 5x slower algo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class SpikeTest2 extends FunSuite with Matchers with DurationTestTools { | |
| val boatPrice = Price(1D, false, 20D) | |
| test("classic algo") { | |
| val season = BoatSeason(TODAY.minusDays(150), TODAY.plusDays(150)) | |
| val specialPeriod = (0 to 50).map { i => SpecialPricePeriod(TODAY.plusDays(i), TODAY.plusDays(i).plusDays(2), i +1) }.toList | |
| val (time, _) = mesureTimeExecutionOf { ClassicAlgo.buildBookingDaysPrice(boatPrice, season, specialPeriod, TODAY, TODAY.plusDays(5)) } | |
| time shouldBeMinusThan (50 milliseconds) | |
| println(time) // ~43 ms | |
| } | |
| test("with extract function algo") { | |
| val season = BoatSeason(TODAY.minusDays(150), TODAY.plusDays(150)) | |
| val specialPeriod = (0 to 50).map { i => SpecialPricePeriod(TODAY.plusDays(i), TODAY.plusDays(i).plusDays(2), i +1) }.toList | |
| val (time, _) = mesureTimeExecutionOf { ExtractAlgo.buildBookingDaysPrice(boatPrice, season, specialPeriod, TODAY, TODAY.plusDays(5)) } | |
| println(time) | |
| time shouldBeMinusThan (50 milliseconds) // ~280 ms | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| object ClassicAlgo { | |
| val ZERO = BookingDaysPrice(0D, 0D) | |
| def buildBookingDaysPrice(boatPrice: Price, | |
| season: BoatSeason, | |
| specialPeriods: List[SpecialPricePeriod], | |
| bookingStartDate: DateTime, | |
| bookingEndDate: DateTime): BookingDaysPrice = { | |
| val seasonDays = extractDaysFromPeriod(season.startDate, season.endDate) | |
| val specialPeriodDays = specialPeriods.map { spe => (extractDaysFromPeriod(spe.startDate, spe.endDate), spe.price) } | |
| val availableDaysPrice: Set[(LocalDate, Price)] = seasonDays.map { day => | |
| val price = specialPeriodDays | |
| .collectFirst { case (speDays, price) if (speDays.contains(day)) => Price(price, boatPrice.inc_vat, boatPrice.vat_value) } | |
| .getOrElse(boatPrice) | |
| (day, price) | |
| } | |
| val bookingDays = extractDaysFromPeriod(bookingStartDate, bookingEndDate) | |
| bookingDays.foldLeft(ZERO) { (acc, day) => | |
| val price = availableDaysPrice | |
| .collectFirst { case (availableDay, price) if(availableDay === day) => price } | |
| .getOrElse(boatPrice) | |
| addBookingPrice(acc, toBookingDaysPrice(price)) | |
| } | |
| } | |
| private def addBookingPrice(p1: BookingDaysPrice, p2: BookingDaysPrice): BookingDaysPrice = | |
| BookingDaysPrice(p1.withVAT + p2.withVAT, p1.withoutVAT + p2.withoutVAT) | |
| private def toBookingDaysPrice(price: Price): BookingDaysPrice = BookingDaysPrice(price.withVAT, price.withoutVAT) | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| object ExtractAlgo { | |
| val ZERO = BookingDaysPrice(0D, 0D) | |
| def buildBookingDaysPrice2(boatPrice: Price, | |
| season: BoatSeason, | |
| specialPeriods: List[SpecialPricePeriod], | |
| bookingStartDate: DateTime, | |
| bookingEndDate: DateTime): BookingDaysPrice = | |
| extractDaysFromPeriod(bookingStartDate, bookingEndDate).foldLeft(ZERO) { (acc, bookingDay) => | |
| val bookingPrice = bookingDay |> calculBookingPrice(season, specialPeriods, boatPrice) |> toBookingDaysPrice | |
| addBookingPrice(acc, bookingPrice) | |
| } | |
| private def calculBookingPrice(season: BoatSeason, specialPeriods: List[SpecialPricePeriod], boatPrice: Price) | |
| (bookingDay: LocalDate): Price = | |
| availableDaysWithPrice(seasonDays, specialPeriodDays)(season, specialPeriods, boatPrice) | |
| .collectFirst { case (availableDay, price) if(availableDay === bookingDay) => price } | |
| .getOrElse(boatPrice) | |
| private def seasonDays: BoatSeason => Set[LocalDate] = season => extractDaysFromPeriod(season.startDate, season.endDate) | |
| private def specialPeriodDays: List[SpecialPricePeriod] => List[(Set[LocalDate], Double)] = specialPeriods => | |
| specialPeriods.map { spe => (extractDaysFromPeriod(spe.startDate, spe.endDate), spe.price) } | |
| private def availableDaysWithPrice(f: BoatSeason => Set[LocalDate], | |
| g: List[SpecialPricePeriod] => List[(Set[LocalDate], Double)]) | |
| (season: BoatSeason, specialPeriods: List[SpecialPricePeriod], boatPrice: Price): Set[(LocalDate, Price)] = | |
| f(season).map { seasonDay => | |
| val price = g(specialPeriods) | |
| .collectFirst { case (speDays, price) if(speDays.contains(seasonDay)) => Price(price, boatPrice.inc_vat, boatPrice.vat_value) } | |
| .getOrElse(boatPrice) | |
| (seasonDay, price) | |
| } | |
| private def addBookingPrice(p1: BookingDaysPrice, p2: BookingDaysPrice): BookingDaysPrice = | |
| BookingDaysPrice(p1.withVAT + p2.withVAT, p1.withoutVAT + p2.withoutVAT) | |
| private def toBookingDaysPrice(price: Price): BookingDaysPrice = BookingDaysPrice(price.withVAT, price.withoutVAT) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment