v
v copied to clipboard
Http.get and http.get_text are really slow while using localhost
V version: V 0.3.0 d75c62b OS: Windows 10 10.0.19044
What did you do?
println('Using 127.0.0.1')
for i := 0; i < 10; i++ {
t := time.now()
first_resp := http.get('http://127.0.0.1:8111') or { panic(err) }
d := time.since(t)
println(d)
}
println('Using localhost')
for i := 0; i < 10; i++ {
t := time.now()
first_resp := http.get('http://localhost:8111') or { panic(err) }
d := time.since(t)
println(d)
}
Results: Using 127.0.0.1 4.000ms 12.000ms 11.000ms 16.000ms 18.000ms 15.000ms 18.000ms 23.000ms 10.000ms 18.000ms Using localhost 5.031s 5.021s 5.016s 5.027s 5.020s 5.024s 5.013s 5.026s 5.018s 5.039s
What server?
This could easily be a server issue. Try the same program in Go.
Sounds more like a name resolution issue. Check C:\Windows\System32\drivers\etc\hosts to see if it has an uncommented entry for localhosts. If not, add one like so
127.0.0.1 localhost
and try again.
If it's not there already, it could definitely explain the time difference... 127.0.0.1 is direct, while it might be trying to hit the network DNS to find out what "localhost" means. :-\
For example, on my Linux system, I created a vweb server:
module main
import vweb
struct App {
vweb.Context
}
pub fn main() {
vweb.run(&App{}, 8003)
}
['/']
fn (mut app App) index() vweb.Result {
return app.text('test')
}
and ran the example code against it. Of course, the number vary wildly, due to other things happening on my system, but they are very similar whether using the IP or localhost... and they're all in microseconds:
Using 127.0.0.1
400.000us
582.000us
298.000us
269.000us
464.000us
123.000us
403.000us
218.000us
388.000us
180.000us
Using localhost
914.000us
170.000us
527.000us
274.000us
439.000us
258.000us
367.000us
184.000us
464.000us
242.000us
My server is a War Thunder client, which sends json files on port 8111. I changed a bit a testing code to show that it's not a server issue: Test code written in Go:
func main() {
println("Using 127.0.0.1")
for i := 0; i < 3; i++ {
t := time.Now()
resp, err := http.Get("http://127.0.0.1:8111")
d := time.Since(t).Milliseconds()
println(d)
_ = resp
if err != nil {
println("Error")
}
}
println("Using localhost")
for i := 0; i < 3; i++ {
t := time.Now()
resp, err := http.Get("http://localhost:8111")
d := time.Since(t).Milliseconds()
println(d)
_ = resp
if err != nil {
println("Error")
}
}
for i := 0; i < 3; i++ {
t := time.Now()
resp, err := http.Get("http://127.0.0.1:8111")
d := time.Since(t).Milliseconds()
println("Using 127.0.0.1:", d)
if err != nil {
println("Error")
}
t = time.Now()
resp, err = http.Get("http://localhost:8111")
d = time.Since(t).Milliseconds()
println("Using localhost:", d)
_ = resp
if err != nil {
println("Error")
}
}
}
Test code written in V:
fn main() {
println('Using 127.0.0.1:')
for i := 0; i < 3; i++ {
t := time.now()
first_resp := http.get('http://127.0.0.1:8111') or { panic(err) }
d := time.since(t)
println(d)
}
println('Using localhost:')
for i := 0; i < 3; i++ {
t := time.now()
first_resp := http.get('http://localhost:8111') or { panic(err) }
d := time.since(t)
println(d)
}
for i := 0; i < 3; i++ {
t_1 := time.now()
first_resp := http.get('http://127.0.0.1:8111') or { panic(err) }
d_1 := time.since(t_1)
println('Using 127.0.0.1: $d_1')
t_2 := time.now()
second_resp := http.get('http://localhost:8111') or { panic(err) }
d_2 := time.since(t_1)
println('Using localhost: $d_2')
}
}
And the results are: Go:
Using 127.0.0.1
12
23
20
Using localhost
324
316
308
Using 127.0.0.1: 11
Using localhost: 313
Using 127.0.0.1: 13
Using localhost: 323
Using 127.0.0.1: 12
Using localhost: 309
V:
Using 127.0.0.1:
5.000ms
14.000ms
37.000ms
Using localhost:
5.019s
5.026s
5.010s
Using 127.0.0.1: 12.000ms
Using localhost: 5.047s
Using 127.0.0.1: 25.000ms
Using localhost: 5.053s
Using 127.0.0.1: 15.000ms
Using localhost: 5.033s
Slower time for localhost in Go is probably caused by the Windows, but still Go is much faster than V.
Also here is my etc/hosts file:
# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
# 102.54.94.97 rhino.acme.com # source server
# 38.25.63.10 x.acme.com # x client host
# localhost name resolution is handled within DNS itself.
# 127.0.0.1 localhost
# ::1 localhost
You need to change this line
d_2 := time.since(t_1)
to
d_2 := time.since(t_2)
Go has their own implementation of dns, so they may have short-circuited the localhost lookup. Uncomment the localhosts lines in your etc/hosts file and try V again.
Note that there isn't much difference between the IP numbers... if you uncomment the line in etc/hosts, there shouldn't be too much difference between the localhost numbers, either.