เวลาที่รวดเร็วสำหรับ Go
f , err := strftime . New ( `.... pattern ...` )
if err := f . Format ( buf , time . Now ()); err != nil {
log . Println ( err . Error ())
}
เป้าหมายของห้องสมุดแห่งนี้คือ
นำรูปแบบและเวลามาจัดรูปแบบ ฟังก์ชันนี้เป็นฟังก์ชันอรรถประโยชน์ที่จะคอมไพล์รูปแบบใหม่ทุกครั้งที่เรียกใช้ฟังก์ชัน หากคุณทราบล่วงหน้าว่าคุณจะจัดรูปแบบรูปแบบเดียวกันหลายครั้ง ให้ลองใช้ New
เพื่อสร้างออบเจ็กต์ Strftime
และนำมาใช้ซ้ำ
ใช้รูปแบบและสร้างวัตถุ Strftime
ใหม่
ส่งกลับสตริงรูปแบบที่ใช้ในการสร้างวัตถุ Strftime
นี้
จัดรูปแบบเวลาตามรูปแบบที่คอมไพล์ไว้ล่วงหน้า และเขียนผลลัพธ์ไปยัง io.Writer
ที่ระบุ
จัดรูปแบบเวลาตามรูปแบบที่คอมไพล์ไว้ล่วงหน้า และส่งกลับสตริงผลลัพธ์
ลวดลาย | คำอธิบาย |
---|---|
%ก | ตัวแทนระดับชาติของชื่อวันทำงานแบบเต็ม |
%ก | ตัวแทนระดับชาติของวันธรรมดาแบบย่อ |
%บี | ตัวแทนระดับชาติของชื่อเดือนเต็ม |
%ข | ตัวแทนระดับชาติของชื่อเดือนแบบย่อ |
%ซี | (ปี/100) เป็นเลขทศนิยม ตัวเลขหลักเดียวนำหน้าด้วยศูนย์ |
%ค | การแสดงเวลาและวันที่ระดับชาติ |
%D | เทียบเท่ากับ %m/%d/%y |
%d | วันของเดือนเป็นเลขทศนิยม (01-31) |
%อี | วันของเดือนเป็นเลขทศนิยม (1-31) ตัวเลขหลักเดียวจะมีช่องว่างนำหน้า |
%เอฟ | เทียบเท่ากับ %Y-%m-%d |
%ชม | ชั่วโมง (นาฬิกาแบบ 24 ชั่วโมง) เป็นเลขทศนิยม (00-23) |
%ชม | เช่นเดียวกับ %b |
%ฉัน | ชั่วโมง (นาฬิกาแบบ 12 ชั่วโมง) เป็นเลขทศนิยม (01-12) |
%เจ | วันของปีเป็นเลขทศนิยม (001-366) |
%เค | ชั่วโมง (นาฬิกาแบบ 24 ชั่วโมง) เป็นเลขทศนิยม (0-23) ตัวเลขหลักเดียวจะมีช่องว่างนำหน้า |
%ลิตร | ชั่วโมง (นาฬิกาแบบ 12 ชั่วโมง) เป็นเลขทศนิยม (1-12) ตัวเลขหลักเดียวจะมีช่องว่างนำหน้า |
%M | นาทีเป็นเลขทศนิยม (00-59) |
%เมตร | เดือนเป็นเลขทศนิยม (01-12) |
%n | ขึ้นบรรทัดใหม่ |
%พี | การเป็นตัวแทนระดับชาติของ "ante meridiem" (am) หรือ "post meridiem" (pm) ตามความเหมาะสม |
%อาร์ | เทียบเท่ากับ %H:%M |
%r | เทียบเท่ากับ %I:%M:%S %p |
%ส | ตัวที่สองเป็นเลขทศนิยม (00-60) |
%T | เทียบเท่ากับ %H:%M:%S |
%t | แท็บ |
%คุณ | เลขสัปดาห์ของปี (วันอาทิตย์เป็นวันแรกของสัปดาห์) เป็นเลขทศนิยม (00-53) |
%คุณ | วันธรรมดา (วันจันทร์เป็นวันแรกของสัปดาห์) เป็นเลขทศนิยม (1-7) |
%วี | ตัวเลขสัปดาห์ของปี (วันจันทร์เป็นวันแรกของสัปดาห์) เป็นเลขทศนิยม (01-53) |
%v | เทียบเท่ากับ %e-%b-%Y |
%วัตต์ | เลขสัปดาห์ของปี (วันจันทร์เป็นวันแรกของสัปดาห์) เป็นเลขทศนิยม (00-53) |
%w | วันธรรมดา (วันอาทิตย์เป็นวันแรกของสัปดาห์) เป็นเลขทศนิยม (0-6) |
%X | ตัวแทนระดับชาติของเวลา |
%x | ตัวแทนระดับชาติของวันที่ |
%ใช่ | ปีโดยมีศตวรรษเป็นเลขทศนิยม |
%y | ปีที่ไม่มีศตวรรษเป็นเลขทศนิยม (00-99) |
%ซี | ชื่อโซนเวลา |
%z | โซนเวลาชดเชยจาก UTC |
- | '%' |
โดยทั่วไปแล้วไลบรารีนี้พยายามที่จะเป็นไปตาม POSIX แต่บางครั้งคุณแค่ต้องการข้อกำหนดพิเศษหรือสองอย่างที่ใช้กันอย่างแพร่หลาย แต่ไม่รวมอยู่ในข้อกำหนด POSIX
ตัวอย่างเช่น POSIX ไม่ได้ระบุวิธีการพิมพ์มิลลิวินาที แต่การใช้งานยอดนิยมอนุญาตให้ %f
หรือ %L
บรรลุเป้าหมายนี้ได้
สำหรับอินสแตนซ์เหล่านั้น คุณสามารถกำหนดค่า strftime.Strftime
เพื่อใช้ชุดข้อกำหนดที่กำหนดเองได้:
ss := strftime.NewSpecificationSet()
ss.Set('L', ...) // provide implementation for `%L`
// pass this new specification set to the strftime instance
p, err := strftime.New(`%L`, strftime.WithSpecificationSet(ss))
p.Format(..., time.Now())
การใช้งานจะต้องใช้อินเทอร์เฟซ Appender
ซึ่งก็คือ
type Appender interface {
Append([]byte, time.Time) []byte
}
สำหรับส่วนขยายที่ใช้กันทั่วไป เช่น ตัวอย่างมิลลิวินาทีและการประทับเวลา Unix เรามีการใช้งานเริ่มต้นเพื่อให้ผู้ใช้สามารถดำเนินการอย่างใดอย่างหนึ่งต่อไปนี้:
// (1) Pass a specification byte and the Appender
// This allows you to pass arbitrary Appenders
p, err := strftime.New(
`%L`,
strftime.WithSpecification('L', strftime.Milliseconds),
)
// (2) Pass an option that knows to use strftime.Milliseconds
p, err := strftime.New(
`%L`,
strftime.WithMilliseconds('L'),
)
ในทำนองเดียวกันสำหรับการประทับเวลา Unix:
// (1) Pass a specification byte and the Appender
// This allows you to pass arbitrary Appenders
p, err := strftime.New(
`%s`,
strftime.WithSpecification('s', strftime.UnixSeconds),
)
// (2) Pass an option that knows to use strftime.UnixSeconds
p, err := strftime.New(
`%s`,
strftime.WithUnixSeconds('s'),
)
หากไม่มีข้อกำหนดทั่วไป โปรดส่ง PR ได้เลย (แต่โปรดตรวจสอบให้แน่ใจว่าสามารถปกป้องได้ว่าข้อกำหนดดังกล่าว "ทั่วไป" เป็นอย่างไร)
Milliseconds
(ตัวเลือกที่เกี่ยวข้อง: WithMilliseconds
);
Microseconds
(ตัวเลือกที่เกี่ยวข้อง: WithMicroseconds
);
UnixSeconds
(ตัวเลือกที่เกี่ยวข้อง: WithUnixSeconds
)
การวัดประสิทธิภาพต่อไปนี้ทำงานแยกกันเนื่องจากไลบรารีบางแห่งใช้ cgo บนแพลตฟอร์มเฉพาะ (โดยเฉพาะอย่างยิ่งเวอร์ชันที่รวดเร็ว)
// On my OS X 10.14.6, 2.3 GHz Intel Core i5, 16GB memory.
// go version go1.13.4 darwin/amd64
hummingbird% go test -tags bench -benchmem -bench .
<snip>
BenchmarkTebeka-4 297471 3905 ns/op 257 B/op 20 allocs/op
BenchmarkJehiah-4 818444 1773 ns/op 256 B/op 17 allocs/op
BenchmarkFastly-4 2330794 550 ns/op 80 B/op 5 allocs/op
BenchmarkLestrrat-4 916365 1458 ns/op 80 B/op 2 allocs/op
BenchmarkLestrratCachedString-4 2527428 546 ns/op 128 B/op 2 allocs/op
BenchmarkLestrratCachedWriter-4 537422 2155 ns/op 192 B/op 3 allocs/op
PASS
ok github.com/lestrrat-go/strftime 25.618s
// On a host on Google Cloud Platform, machine-type: f1-micro (vCPU x 1, memory: 0.6GB)
// (Yes, I was being skimpy)
// Linux <snip> 4.9.0-11-amd64 #1 SMP Debian 4.9.189-3+deb9u1 (2019-09-20) x86_64 GNU/Linux
// go version go1.13.4 linux/amd64
hummingbird% go test -tags bench -benchmem -bench .
<snip>
BenchmarkTebeka 254997 4726 ns/op 256 B/op 20 allocs/op
BenchmarkJehiah 659289 1882 ns/op 256 B/op 17 allocs/op
BenchmarkFastly 389150 3044 ns/op 224 B/op 13 allocs/op
BenchmarkLestrrat 699069 1780 ns/op 80 B/op 2 allocs/op
BenchmarkLestrratCachedString 2081594 589 ns/op 128 B/op 2 allocs/op
BenchmarkLestrratCachedWriter 825763 1480 ns/op 192 B/op 3 allocs/op
PASS
ok github.com/lestrrat-go/strftime 11.355s
ไลบรารีนี้เร็วกว่าไลบรารีอื่นมาก หาก คุณสามารถนำรูปแบบการจัดรูปแบบกลับมาใช้ใหม่ได้
นี่คือรายการคำอธิบายประกอบจากผลลัพธ์การวัดประสิทธิภาพ คุณจะเห็นได้อย่างชัดเจนว่า (อีกครั้ง) การใช้วัตถุ Strftime
และสร้างสตริงนั้นเร็วที่สุด การเขียนถึง io.Writer
ดูเหมือนจะเชื่องช้าเล็กน้อย แต่เนื่องจากผู้สร้างสตริงนั้นทำสิ่งเดียวกันเกือบทั้งหมด เราจึงเชื่อว่านี่เป็นค่าใช้จ่ายในการเขียนถึง io.Writer
ล้วนๆ
เส้นทางการนำเข้า | คะแนน | บันทึก |
---|---|---|
github.com/lestrrat-go/strftime | 3000000 | การใช้ FormatString() (แคช) |
github.com/fastly/go-utils/strftime | 2000000 | เวอร์ชัน Pure Go บน OS X |
github.com/lestrrat-go/strftime | 1000000 | การใช้ Format() (ไม่แคช) |
github.com/jehiah/go-strftime | 1000000 | |
github.com/fastly/go-utils/strftime | 1000000 | เวอร์ชัน cgo บน Linux |
github.com/lestrrat-go/strftime | 500000 | การใช้ Format() (แคช) |
github.com/tebeka/strftime | 300000 |
อย่างไรก็ตาม ความเร็วนี้อาจแตกต่างออกไป ขึ้นอยู่กับรูปแบบของคุณ หากคุณพบรูปแบบใดรูปแบบหนึ่งที่ดูซบเซา โปรดส่งแพทช์หรือการทดสอบ
โปรดทราบว่าเกณฑ์มาตรฐานนี้ใช้เฉพาะชุดย่อยของข้อกำหนดการแปลงที่ไลบรารี ทั้งหมด รองรับเมื่อเปรียบเทียบ
สิ่งที่ควรพิจารณาเมื่อทำการเปรียบเทียบประสิทธิภาพในอนาคต:
%specification
ใด?