4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめてのアドベントカレンダーAdvent Calendar 2024

Day 6

#Javascript #プログラミング # #atcoder や #paiza の #競技プログラミング で気づいた #nodejs の不可解な挙動

Last updated at Posted at 2024-11-01

本内容を利用した場合の一切の責任を私は負いません。

概要

作成中や提出前に、確認でローカル実行した時に気づいたこと。
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を入れても起こる。
(重さの影響が強くなるからなのか、崩れも大きくなる。)
もしくは、自分がとんでもない勘違いをしているか(笑)

4
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?