Browse Source

Optimise day 2 some more.

Specify whether the VM uses IO or not, and if not don't create
channels. These are more expensive than I expected, and
pointlessly creating/destroying them thousands of times is
a significant CPU drain.
master
Chris Smith 4 years ago
parent
commit
62c511e66a
Signed by: Chris Smith <chris@chameth.com> GPG Key ID: 3A2D4BBDC4A3C9A9
4 changed files with 21 additions and 12 deletions
  1. 1
    1
      02/main.go
  2. 1
    1
      05/main.go
  3. 17
    8
      intcode/vm.go
  4. 2
    2
      intcode/vm_test.go

+ 1
- 1
02/main.go View File

39
 
39
 
40
 	pool := &sync.Pool{
40
 	pool := &sync.Pool{
41
 		New: func() interface{} {
41
 		New: func() interface{} {
42
-			return intcode.NewVirtualMachine(make([]int, len(input)))
42
+			return intcode.NewVirtualMachine(make([]int, len(input)), false)
43
 		},
43
 		},
44
 	}
44
 	}
45
 
45
 

+ 1
- 1
05/main.go View File

22
 	memory := make([]int, len(input))
22
 	memory := make([]int, len(input))
23
 	copy(memory, input)
23
 	copy(memory, input)
24
 
24
 
25
-	vm := intcode.NewVirtualMachine(memory)
25
+	vm := intcode.NewVirtualMachine(memory, true)
26
 	vm.Input <- 1
26
 	vm.Input <- 1
27
 	go vm.Run()
27
 	go vm.Run()
28
 	fmt.Println(last(vm.Output))
28
 	fmt.Println(last(vm.Output))

+ 17
- 8
intcode/vm.go View File

13
 
13
 
14
 // NewVirtualMachine creates a new IntCode virtual machine, initialised
14
 // NewVirtualMachine creates a new IntCode virtual machine, initialised
15
 // to the given slice of memory.
15
 // to the given slice of memory.
16
-func NewVirtualMachine(memory []int) *VirtualMachine {
17
-	return &VirtualMachine{
16
+func NewVirtualMachine(memory []int, hasIO bool) *VirtualMachine {
17
+	vm := &VirtualMachine{
18
 		ip:     0,
18
 		ip:     0,
19
 		Memory: memory,
19
 		Memory: memory,
20
 		Halted: false,
20
 		Halted: false,
21
-		Input:  make(chan int, 1),
22
-		Output: make(chan int, 1),
23
 		opcodes: [100]interface{}{
21
 		opcodes: [100]interface{}{
24
 			1:  AddOpcode,
22
 			1:  AddOpcode,
25
 			2:  MulOpcode,
23
 			2:  MulOpcode,
32
 			99: HaltOpcode,
30
 			99: HaltOpcode,
33
 		},
31
 		},
34
 	}
32
 	}
33
+
34
+	if hasIO {
35
+		vm.Input = make(chan int, 1)
36
+		vm.Output = make(chan int, 1)
37
+	}
38
+
39
+	return vm
35
 }
40
 }
36
 
41
 
37
 func (vm *VirtualMachine) arg(pos int) int {
42
 func (vm *VirtualMachine) arg(pos int) int {
60
 
65
 
61
 		vm.opcodes[opcode].(OpcodeFunc)(vm)
66
 		vm.opcodes[opcode].(OpcodeFunc)(vm)
62
 	}
67
 	}
63
-	close(vm.Input)
64
-	close(vm.Output)
68
+	if vm.Input != nil {
69
+		close(vm.Input)
70
+		close(vm.Output)
71
+	}
65
 }
72
 }
66
 
73
 
67
 // Reset resets the memory to the given slice, and all other state back to its original value.
74
 // Reset resets the memory to the given slice, and all other state back to its original value.
69
 	copy(vm.Memory, memory)
76
 	copy(vm.Memory, memory)
70
 	vm.ip = 0
77
 	vm.ip = 0
71
 	vm.Halted = false
78
 	vm.Halted = false
72
-	vm.Input = make(chan int, 1)
73
-	vm.Output = make(chan int, 1)
79
+	if vm.Input != nil {
80
+		vm.Input = make(chan int, 1)
81
+		vm.Output = make(chan int, 1)
82
+	}
74
 }
83
 }

+ 2
- 2
intcode/vm_test.go View File

17
 	}
17
 	}
18
 
18
 
19
 	for _, table := range tables {
19
 	for _, table := range tables {
20
-		vm := NewVirtualMachine(table.given)
20
+		vm := NewVirtualMachine(table.given, false)
21
 		vm.Run()
21
 		vm.Run()
22
 		if !reflect.DeepEqual(table.expected, vm.Memory) {
22
 		if !reflect.DeepEqual(table.expected, vm.Memory) {
23
 			t.Errorf("Evaluation of %v was incorrect, got: %v, want: %v.", table.given, vm.Memory, table.expected)
23
 			t.Errorf("Evaluation of %v was incorrect, got: %v, want: %v.", table.given, vm.Memory, table.expected)
48
 	}
48
 	}
49
 
49
 
50
 	for _, table := range tables {
50
 	for _, table := range tables {
51
-		vm := NewVirtualMachine(table.given)
51
+		vm := NewVirtualMachine(table.given, true)
52
 
52
 
53
 		for _, v := range table.input {
53
 		for _, v := range table.input {
54
 			vm.Input <- v
54
 			vm.Input <- v

Loading…
Cancel
Save