本内容を利用した場合の一切の責任を私は負いません。
概要
作成中や提出前に、確認でローカル実行した時に気づいたこと。
consoleは非同期???
もしくは、node.jsは投機実行する???
バージョン
- OS
OS 名: Microsoft Windows 10 Home
OS バージョン: 10.0.19045 N/A ビルド 19045
システムの種類: x64-based PC - Visuatl Studio Code(以降、VSC)
バージョン: 1.38.1 - node.js
node-v20.9.0-win-x64.zip
詳細
下記のソースをVSC上で実行する。
var a = [];
function sub() {
for (let index = 0; index < 10; index++) {
a.push(new Array(10));
}
//領域確保遅延かもしれないため、確保を確定させるため。
for (let indexY = 0; indexY < a.length; indexY++) {
for (let indexX = 0; indexX < a[indexY].length; indexX++) {
a[indexY][indexX] = "0";
}
}
}
async function main() {
//領域確保未完で投機実行を防ぐため。
await sub();
for (let index = 0; index < 5; index++) {
console.log("#start", index)
for (let count = 0; count < a.length; count++) {
const t = a[count];
console.log(t);
}
a[0][0] = "z";
console.log("#end")
for (let count = 0; count < a.length; count++) {
const t = a[count];
console.log(t);
}
}
}
main();
大したことはやってない。
10x10の配列を作り、全要素に"0"を格納する。
その後、5回のループの中で、配列の[0][0]に"z"を格納するが、格納前と後で全配列を出力する。
下記の出力になる。
(行頭の行番号は、説明の都合上、後付けした。)
2 Debugger listening on ws://127.0.0.1:30672/f73e4aef-5c98-421d-88a1-6971e5762905
3 For help, see: https://nodejs.org/en/docs/inspector
4 Debugger attached.
5 #start 0
6 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
7 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
8 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
9 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
10 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
11 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
12 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
13 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
14 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
15 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
16 #end
17 null: Array(10) ["z", "0", "0", "0", "0", "0", "0", "0", …]
18 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
19 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
20 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
21 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
22 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
23 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
24 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
25 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
26 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
27 #start 1
28 null: Array(10) ["z", "0", "0", "0", "0", "0", "0", "0", …]
29 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
30 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
31 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
32 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
33 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
34 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
35 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
36 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
37 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
38 #end
39 null: Array(10) ["z", "0", "0", "0", "0", "0", "0", "0", …]
40 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
41 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
42 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
43 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
44 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
45 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
46 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
47 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
48 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
49 #start 2
50 null: Array(10) ["z", "0", "0", "0", "0", "0", "0", "0", …]
51 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
52 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
53 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
54 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
55 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
56 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
57 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
58 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
59 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
60 #end
61 null: Array(10) ["z", "0", "0", "0", "0", "0", "0", "0", …]
62 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
63 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
64 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
65 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
66 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
67 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
68 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
69 #start 3
70 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
71 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
72 null: Array(10) ["z", "0", "0", "0", "0", "0", "0", "0", …]
73 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
74 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
75 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
76 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
77 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
78 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
79 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
80 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
81 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
82 #end
83 null: Array(10) ["z", "0", "0", "0", "0", "0", "0", "0", …]
84 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
85 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
86 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
87 #start 4
88 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
89 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
90 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
91 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
92 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
93 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
94 null: Array(10) ["z", "0", "0", "0", "0", "0", "0", "0", …]
95 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
96 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
97 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
98 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
99 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
100 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
101 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
102 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
103 #end
104 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
105 null: Array(10) ["z", "0", "0", "0", "0", "0", "0", "0", …]
106 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
107 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
108 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
109 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
110 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
111 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
112 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
113 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
114 null: Array(10) ["0", "0", "0", "0", "0", "0", "0", "0", …]
"z"を出力している位置を注目して欲しい。
配列の先頭であるため、全配列の出力の先頭で出力されるはずである。
それは、処理順から、startやendの直後に出力されるはずである。
しかし、例えば72行目は違う。。。
考察
概要にも書いたが、何故かはわからない。
とりあえず、スコープが異なる(?)consoleは時系列ではないかもしれないことを考慮した方がいい。
競技プログラミングで試し出力が間違っていても、それはこのための可能性もある。
デバッグ時のトレースも考慮が必要だろう。
因果関係があるかわからないが、paizaのWeb上のコードテストでは現象は起きなかった。
この記事の前の記事で本番環境判別を書いたが、paizaの環境は環境変数を見るとOSが定義されていなかったりするため、特殊な環境の可能性もある。
大量に処理すると思われるため、動作の鈍さがあり、それ故にたまたま時系列になるということもあるかもしれない。
処理の重さという観点なら、startやendのヘッダ出力より、配列を誤魔化して出力する方がかなり重いため、それが関係している可能性もある。
consoleの前にawaitを入れても起こる。
(重さの影響が強くなるからなのか、崩れも大きくなる。)
もしくは、自分がとんでもない勘違いをしているか(笑)