Browse Source

Refactor for speed optimizations...

Make the Clock type an int, rather than a struct
  Inline the hour/minute conversions on String()
  Inline the calculation of total and its modulo to minutesPerDay
  Benchmarks show ~35% improvement
master
jimi 9 years ago
parent
commit
a9ebf1b548
  1. 4
      bench1
  2. 44
      clock.go

4
bench1

@ -0,0 +1,4 @@
PASS
BenchmarkAddMinutes-12 50000000 29.7 ns/op
BenchmarkCreateClocks-12 50000000 33.9 ns/op
ok exercism/go/clock 3.252s

44
clock.go

@ -1,57 +1,45 @@
// Package clock represents a dateless time of day.
package clock package clock
import "fmt" import "fmt"
const ( const (
testVersion = 3 testVersion = 3
hoursPerDay = 24
minutesPerHour = 60 minutesPerHour = 60
minutesPerDay = 1440 minutesPerDay = 1440
) )
// A Clock stores a minute value representing a time of day. // A Clock stores a minute value representing a time of day.
type Clock struct {
minutes int
}
type Clock int
// String returns an hour:minute representation of the Clock. // String returns an hour:minute representation of the Clock.
func (c Clock) String() string { func (c Clock) String() string {
return fmt.Sprintf("%02d:%02d", c.hour(), c.mins())
return fmt.Sprintf("%02d:%02d", c/minutesPerHour, c%minutesPerHour)
} }
// Add returns a Clock adjusted by the number of minutes specified. // Add returns a Clock adjusted by the number of minutes specified.
func (c Clock) Add(minutes int) Clock { func (c Clock) Add(minutes int) Clock {
c.minutes = parseTime(0, c.minutes+minutes)
return c
}
// hour computes the hourly portion of the Clock.
func (c Clock) hour() int {
return c.minutes / minutesPerHour
}
// mins computes the non-hourly remainder of the Clock.
func (c Clock) mins() int {
return c.minutes % minutesPerHour
return parseTime(0, int(c)+minutes)
} }
// New returns a Clock constructed from the given hour and minute values. // New returns a Clock constructed from the given hour and minute values.
func New(hour, minutes int) Clock { func New(hour, minutes int) Clock {
return Clock{parseTime(hour, minutes)}
return parseTime(hour, minutes)
} }
// parseTime computes the number of minutes that represent the time. // parseTime computes the number of minutes that represent the time.
func parseTime(hour, minutes int) int {
// normalize hours that are out of range [0-23]
hour = hour % hoursPerDay
// normalize any out of range values [0-1439]
minutes = minutes % minutesPerDay
// compute the total minutes
total := hour * minutesPerHour
total += minutes
// normalize any negative minute values
func parseTime(hour, minutes int) Clock {
// Compute the total minutes, factoring away multiple day values.
total := (hour*minutesPerHour + minutes) % minutesPerDay
// If total minutes is negative, roll forward one day.
if total < 0 { if total < 0 {
total += minutesPerDay total += minutesPerDay
} }
return total
return Clock(total)
} }
// Benchmark versus previous iteration:
//
// benchmark old ns/op new ns/op delta
// BenchmarkAddMinutes-12 45.7 29.7 -35.01%
// BenchmarkCreateClocks-12 52.1 33.9 -34.93%
Loading…
Cancel
Save