部分1-4)データ構造とデータ型-8)周波数ホッピングと周波数ホッピングセット

26116 ワード


Week MapとWeek Set部分リンク:https://ko.javascript.info/weakmap-weakset
JAvascriptエンジンは、メモリに到達可能な(および後で使用可能な)値を保持します.(注:ゴミ収集https://ko.javascript.info/garbage-collection)
let john = { name: "John" }; // 참조

// 위 객체는 john이라는 참조를 통해 접근할 수 있다.

// 그런데 참조를 null로 덮어쓰면 위 객체에 더 이상 도달이 가능하지 않게 되어 
// 객체가 메모리에서 삭제된다.
john = null;
データ構造を構成する要素(地図、三等のデータ構造を構成する要素)は、その属するデータ構造がメモリに残っている場合、通常は達成可能な値とみなされ、メモリから削除されない.オブジェクトの輪郭または配列を構成する要素、マッピングまたは3つの要素.
たとえば、オブジェクトを要素としてアレイに追加すると、アレイ内の要素であるアレイ内の要素もメモリに残ります.アレイがメモリに残っていない限り.配列はメモリに存在するため、オブジェクトが参照されていなくてもメモリに保持されます.
let john = { name: "John" };

let array = [ john ];

john = null; // 참조를 null로 덮어씀

// john을 나타내는 객체는 배열(메모리에 남아있는 자료구조)의 요소이기 때문에 가비지 컬렉터의 대상이 되지 않는다.
// array[0]을 이용하면 해당 객체를 얻는 것도 가능하다.
alert(JSON.stringify(array[0]));
マッピングでオブジェクトをキーとして使用する場合、オブジェクトはメモリにマッピングされている限りメモリに保持されます.つまり、ゴミ収集器のターゲットにはなりません.
let john = { name: "John" };

let map = new Map();
map.set(john, "...");

john = null; // 참조를 null로 덮어씀

// john을 나타내는 객체는 맵 안에 저장되어있다.
// map.keys()를 이용하면 해당 객체를 얻는 것도 가능하다.
// 참조를 null로 덮어써도 맵 안에 저장된 객체 john은 그대로 존재하는 것.
for(let obj of map.keys()){
  alert(JSON.stringify(obj)); 
  // 맵에 저장된 객체의 key를 호출, {"name": "John"}
}

alert(map.size);
このような観点の下で、WeakMapは普通の地図とは全く異なる表現を持っている.Week Mapを使用する場合、上記の例でキーとして使用したオブジェクトがゴミ収集の対象となります.

作業概要


マップとマップの最初の違いは、マップのキーがオブジェクトである必要があることです.元の値はビットマップのキーとして使用できません.
let weakMap = new WeakMap();

let obj = {};

weakMap.set(obj, "ok"); //정상적으로 동작합니다(객체 키).

// 문자열("test", 원시형)은 키로 사용할 수 없다.
weakMap.set("test", "Whoops"); // Error: Invalid value used as weak map key
ビットマップキーとして使用されるオブジェクトが参照されていない場合は、メモリとビットマップから自動的に削除されます.
つまり、ゴミ収集器の対象になります.
let john = { name: "John" };

let weakMap = new WeakMap();
weakMap.set(john, "...");

john = null; // 참조를 덮어씀

// john을 나타내는 객체는 이제 메모리에서 지워진다!
for(let obj of weakMap.keys()){
  alert(JSON.stringify(obj)); 
} // john 객체가 메모리에서 지워지고 위크맵에서도 자동으로 지워졌기 때문에 아무 동작도 일어나지 않는다.
johnを表すオブジェクトは「workmap」のキーとしてのみ使用されるため、参照を上書きすると「workmap」とメモリから自動的に削除されます.
マップとマップの2つ目の違いは、マップが繰り返し操作とkeys()、values()、entries()メソッドをサポートしていないことです.
したがって、ビットマップでは、キーまたは値全体を取得することはできません.
次に、ビットマップでサポートされている方法を示します.
weakMap.get(key)
weakMap.set(key, value)
weakMap.delete(key)
weakMap.has(key)
以上のようにWeek Mapが4つの方法しかサポートしていないのは,ごみ収集の動作方式が原因である.上記の例でjohnを表すオブジェクトと同様に、オブジェクトがすべての参照を失うと(=達成できない場合)、自動的に「不要なセット」のターゲットになります.しかし、ゴミ収集の動作時間はまだ分からない.
ごみ収集の発生時期はJavaScriptエンジンで決定します.オブジェクトがすべての参照を失うと、すぐにメモリから削除したり、他の削除操作を待っている間に削除したりできます.
すなわち、ビットマップの要素(オブジェクト)がいつ削除されるか分からないため、現在のビットマップにどれだけの要素があるかを正確に知ることはできない.ゴミ収集器は、メモリを一度に消去したり、ローカルメモリを消去したりすることができるため、ビットマップ全体の要素(キー/値)に対していくつかの操作を実行すること自体は不可能です.
以下はビットマップを利用できる場合です.
1)その他のデータ
追加データを格納する場所が必要な場合、Week Mapはその価値を発揮します.
サードパーティ製ライブラリなどの外部コードで「属する」オブジェクトを使用する必要がある場合は、そのオブジェクトにデータを追加する必要がありますが、追加するデータはオブジェクトが生きている場合にのみ有効です.この場合はビットマップを使用できます.
必要なデータをビットマップに格納し、キーオブジェクトを使用すると、オブジェクトがゴミ収集のターゲットになると、データも消えます.
オブジェクトがすべての参照を失った場合、オブジェクトはビットマップから消え、オブジェクト自体も消えます.
weakMap.set(john, "비밀문서");
// john이 사망하면, 비밀문서는 자동으로 파기됩니다.
次の例では、ユーザーのアクセス回数を計算できるコードを示します.
関連情報はマッピングに格納され、マッピング要素のキーは特定のユーザのオブジェクトを表し、値はそのユーザのアクセス回数を表す.ユーザの情報を保存する必要がない場合(ユーザがゴミ収集のターゲットである場合)、ユーザのアクセス回数を保存する必要もありません.
次の関数では、マッピングを使用してユーザーのアクセス数を計算します.
// 📁 visitsCount.js
let visitsCountMap = new Map(); // 맵에 사용자의 방문 횟수를 저장함

// 사용자가 방문하면 방문 횟수가 1씩 증가한다.
function countUser(user) {
  let count = visitsCountMap.get(user) || 0;
  visitsCountMap.set(user, count + 1);
}
次に、Johnという名前のユーザーがアクセスするときに、アクセス回数がどのように増加するかを示します.
// 📁 main.js
let john = { name: "John" };

countUser(john); // John의 방문 횟수를 증가시킨다.

// John의 방문 횟수를 셀 필요가 없어지면 아래와 같이 john을 null로 덮어써서 참조를 없앤다.
john = null;
johnを表すオブジェクトはゴミ収集のオブジェクトであるべきです...まさか.johnはWeakMapではなくVisitsCountMapの鍵なのでメモリからは削除されません.(前述したように、データ構造を構成する要素は、その属するデータ構造がメモリに保持されている場合、通常は達成可能な値とみなされ、メモリから削除されません.)
特定のユーザを表すオブジェクトがメモリから消えた場合、そのオブジェクトの情報を手動で消去する必要があります(Mapでオブジェクトをキーとし、Valueに格納されているアクセス回数).このように手動で消去しないと、visitsCountMapが消費するメモリ容量は無限に大きくなります.アプリケーション構造が複雑な場合、これらの不要なデータを手動で空にするのも複雑です.
この問題はWeek Mapを使うことで予防できます.^^
// 📁 visitsCount.js
let visitsCountMap = new WeakMap(); // 위크맵에 사용자의 방문 횟수를 저장

// 사용자가 방문하면 방문 횟수를 늘려준다.
function countUser(user) {
  let count = visitsCountMap.get(user) || 0;
  visitsCountMap.set(user, count + 1);
}
[リンクマッピング](Link Mapping)を使用してユーザアクセス数を保存する場合、[リンクマッピング](Link Mapping)にキーワードとして保存されているオブジェクトがメモリから消えた場合、visitsCountMapを手動でクリアする必要はありません.
なぜなら、johnを表すオブジェクトが到達不可能である場合、Week Mapキーであるjohnとvalue(johnのアクセス回数)も自動的に不要な集合のターゲットとなり、メモリから削除されるからである.
2)キャッシュ
キャッシュが必要な場合は、ビットマップが便利です.キャッシュは、時間のかかるタスクの結果を格納することで、計算時間とコストを節約する技術です.たとえば、キャッシュでは、同じ関数を複数回呼び出す必要がある場合、最初に呼び出された値をある場所に保存し、関数を呼び出すのではなく、保存された値を使用します.
次の例では、関数の演算結果をマッピングに保存します.(マッピングをキャッシュとして使用)
// 📁 cache.js
let cache = new Map();

// 연산을 수행하고 그 결과를 맵에 저장
function process(obj) {
  //cache에 obj가 없으면
  if (!cache.has(obj)) {
    let result = /* 연산 수행 */ obj;

    cache.set(obj, result);
  }

  return cache.get(obj);
}

// 함수 process()를 호출해봅시다.

// 📁 main.js
let obj = {/* ... 객체 ... */};

let result1 = process(obj); // 함수 호출

// 동일한 함수를 두 번째 호출할 땐,
let result2 = process(obj); // 연산을 수행할 필요 없이 맵에 저장된 결과를 가져오면 된다.

// 객체가 쓸모없어지면 아래와 같이 null로 덮어써서 모든 참조 없앰
obj = null;

alert(cache.size); // 1 (객체가 여전히 cache에 남아있다! 메모리가 낭비되고 있음)
マルチコールprocess(obj)は、初回呼び出し時にのみ演算を実行し、cacheから演算結果を取得します.ただし、マッピングを使用する場合は、オブジェクトを必要としなくてもcacheを手動でクリーンアップします.キーとしてオブジェクトを使用するMap(Cache)がまだ存在するためです.
マップをビットマップに置き換えると、オブジェクトがメモリから削除されると、キャッシュに格納された結果(関数演算の結果)もメモリから自動的に削除されます.
したがって、上記の問題を解決するには、ビットマップを使用することができる.
// 📁 cache.js
let cache = new WeakMap();

// 연산을 수행하고 그 결과를 위크맵에 저장
function process(obj) {
  if (!cache.has(obj)) {
    let result = /* 연산 수행 */ obj;

    cache.set(obj, result);
  }

  return cache.get(obj);
}

// 📁 main.js
let obj = {/* ... 객체 ... */};

let result1 = process(obj);
let result2 = process(obj);

// 객체가 쓸모없어지면 아래와 같이 null로 덮어써서 모든 참조 없앰
obj = null;

// obj는 weakMap의 key로 사용되어 참조가 모두 사라지면 가비지 컬렉션의 대상이 되므로, 캐싱된 데이터 역시 메모리에서 삭제된다.
// 삭제가 진행되면 cache엔 그 어떤 요소도 남아있지 않게 된다.

WeakSet


Week SetはSetに似ていますが、オブジェクトのみを格納できる点が異なります.元の値は保存できません.
3つのオブジェクトは、到達可能な場合にのみメモリに保持されます.
3人と同じように、3人でサポートする方法は多くありません.
add、has、deleteは使用できますが、size、keys()または繰返しタスクに関連するメソッドは使用できません.
[週](Week)マッピングと同様に、[週](Week)セットを使用して追加データを格納することもできます.ただし、WeekSetはWeek Mapのように複雑なデータを格納しません.「はい」や「いいえ」などの簡単な回答を得るために使用されます.(もちろん対象の形で)
次のコードは、Weeksetを使用してユーザーがサイトにアクセスするかどうかを追跡する例です.
let visitedSet = new WeakSet();

let john = { name: "John" };
let pete = { name: "Pete" };
let mary = { name: "Mary" };

visitedSet.add(john); // 1) John이 사이트를 방문
visitedSet.add(pete); // 2) 이어서 Pete가 사이트를 방문
visitedSet.add(john); // 3) 이어서 John이 다시 사이트를 방문

// visitedSet엔 두 명의 사용자가 저장된다. (set은 중복을 허용하지 않으니까)

// John의 방문 여부 확인
alert(visitedSet.has(john)); // true

// Mary의 방문 여부 확인
alert(visitedSet.has(mary)); // false

john = null; //john의 모든 참조 없앰

// visitedSet에서 john을 나타내는 객체가 자동으로 삭제된다.
Week MapとWeek Setの最大の欠点は、作業を繰り返すことができないことです.Week MapまたはWeek Setに保存されている資料を一度に入手することは不可能です.重複機能がないと不便そうに見えますが、Week MapやWeek Setを利用した主な作業を妨げることはありません.[ビットマップ](Bitmap)および[週刊誌セット](Week Sets)は、オブジェクトとともに[アタッチ](Attach)データを格納するために使用できます.