看到同事这么写的时间比较
if now < "2019-04-10 19:00:00" {
result["isDo"] = 0
}else if now > "2019-04-11 00:00:00" {
result["isDo"] = 2
}else {
result["isDo"] = 1
}
震惊了,居然可以这么写。自己试了下,可以比较
但是网上搜索了一下,居然没找到相关的说明。想知道这样写的原理是什么
1
www5070504 2019-03-28 19:04:51 +08:00
按 ascii 码逐个字符比较?
|
2
dremy 2019-03-28 19:05:28 +08:00 via iPhone
ascii 比较呗,肯定是能比的
|
3
cpdyj0 2019-03-28 19:07:50 +08:00
没用过 Go,处理 ASCII 比较,会不会是运算符重载之类的?(不知道 Go 有没有这种东西)
|
4
mengzhuo 2019-03-28 19:31:06 +08:00
字符比较,按 ascii,当然可以啦,效率嘛……比 time.Time 慢至少 2 倍多
不过有些特殊情况就搞不定了,比如说两个不同时区的时间比较~(虽然国内程序员很少遇到) |
5
misaka19000 2019-03-28 19:34:56 +08:00
某些情况下是能比较的,不过能写出这种代码的程序员水平也真是拙计
|
6
liyunlong41 2019-03-28 19:51:12 +08:00 via iPhone
@mengzhuo 有 benchmarks 吗?很好奇为啥会慢
|
7
pwrliang 2019-03-28 19:55:38 +08:00 via Android
逐个字符比较呗,SQL 里经常这么写,感觉会比转换成日期类型还快
|
8
iRiven 2019-03-28 19:58:00 +08:00 via Android
有才华 比解析一遍时间来的效率
|
9
blankme 2019-03-28 19:59:18 +08:00 via Android
@liyunlong41
timestamp 比较只需要比一次数字,string 比较的话,一个一个字符比。。。 |
12
gamexg 2019-03-28 20:40:22 +08:00 1
package main
import ( "fmt" "time" ) func main() { testData := "2006-01-02 15:04:05" nowStr := time.Now().Format("2006-01-02 15:04:05") f1 := func() bool { return testData > nowStr } f2 := func() bool { nowStr := time.Now().Format("2006-01-02 15:04:05") return testData > nowStr } f3 := func() bool { t, err := time.Parse("2006-01-02 15:04:05", testData) if err != nil { panic(err) } return time.Now().After(t) } T("字符串比较", f1) T("now 转换为字符串后和字符串比较", f2) T("字符串解析为 time 后比较", f3) } func T(name string, f func() bool) { s := time.Now() for i := 0; i < 1000000; i++ { f() } fmt.Printf("%v 耗时 %v\r\n", name, time.Now().Sub(s)) } 字符串比较 耗时 5.0145ms now 转换为字符串后和字符串比较 耗时 203.3878ms 字符串解析为 time 后比较 耗时 190.563ms |
14
laminux29 2019-03-28 21:00:50 +08:00 2
[YYYY-MM-dd HH:mm:ss.fff] 格式的字符串,能进行比较的本质原因,是因为该字符串是一种 [进位数值系统] 。
整数 123456 这种是以 10 作为进位的数值系统,它能进行比较。 而 [YYYY-MM-dd HH:mm:ss.fff] 格式的字符串,也是进位的数值系统,只是它的进位是非固定的,比如时分位是右位 12 进 1,但月位却是右位 28、30、31 进 1。 |
15
yippees 2019-03-28 21:28:42 +08:00
now 也是 time.Now()转的吧,转换成数字比较更快吧
如果涉及到金钱相关,跨个时区 |
16
WilliamYang 2019-03-28 21:52:13 +08:00
这个时间格式本来就不带有时区, 当然可以这样比较啊
|
17
skiy 2019-03-28 22:03:08 +08:00
...
我一般是转成时间戳再比较的,我是不是做错了? |
19
mengzhuo 2019-03-29 09:36:37 +08:00 1
@blankme 并不是,Go 会用 AVX 并行优化这部分代码,而字符串时间是 19 个字节,19*8 = 152 < 256。一次比较就能得出结果。大概率是慢在内存加载上(懒得做分析了,摊手~
@liyunlong41 嗯,有探索精神,可惜懒了点。 我跑了跑,不是 2 倍( 100%),是~70%。 差别嘛~自己看 objdump 吧 ``` func BenchmarkISOString(b *testing.B) { a := "2019-04-10 19:00:00" c := "2019-04-10 19:00:01" b.ResetTimer() for i := 0; i < b.N; i++ { _ = a < c } } func BenchmarkTime(b *testing.B) { a := time.Now() c := time.Now().Add(time.Second) b.ResetTimer() for i := 0; i < b.N; i++ { _ = a.Before(c) } } goos: linux goarch: amd64 BenchmarkISOString-12 200000000 6.68 ns/op BenchmarkISOString-12 200000000 6.71 ns/op BenchmarkISOString-12 200000000 6.55 ns/op BenchmarkTime-12 500000000 3.89 ns/op BenchmarkTime-12 500000000 4.07 ns/op BenchmarkTime-12 500000000 3.93 ns/op PASS ok _/root/hoho 13.189s ``` |