ਮੈਂ ਹਰ ਸ਼ਬਦ ਨੂੰ ਇੱਕ ਵਾਰ ਗਿਣਨ ਲਈ ਦੋ ਵਾਰ ਹੈਸ਼ ਕੀਤਾ
ਮੈਂ ਪਿਛਲੇ ਹਫ਼ਤੇ ਇੱਕ ਲੌਗ ਪਾਰਸਰ (log parser) ਦਾ ਪ੍ਰੋਫਾਈਲ ਕੀਤਾ। ਇਹ ਰੋਜ਼ਾਨਾ ਲੌਗ ਵਿੱਚ ਐਰਰ ਕੋਡ (error codes) ਗਿਣਦਾ ਹੈ। ਇਸਦਾ ਮੁੱਖ ਤਰਕ (logic) ਇੱਕ ਸਧਾਰਨ ਡਿਕਸ਼ਨਰੀ ਅੱਪਡੇਟ ਹੈ।
ਜ਼ਿਆਦਾਤਰ ਡਿਵੈਲਪਰ ਇਸਨੂੰ ਇਸ ਤਰ੍ਹਾਂ ਲਿਖਦੇ ਹਨ:
if (counts.TryGetValue(code, out int c))
counts[code] = c + 1;
else
counts[code] = 1;
ਇਹ ਕੋਡ ਕੀ (key) ਨੂੰ ਦੋ ਵਾਰ ਹੈਸ਼ ਕਰਦਾ ਹੈ। TryGetValue ਹੈਸ਼ ਦੀ ਗਣਨਾ ਕਰਕੇ ਅਤੇ ਬੱਕਟ (bucket) ਵਿੱਚ ਜਾ ਕੇ ਐਂਟਰੀ ਲੱਭਦਾ ਹੈ। ਫਿਰ ਇੰਡੈਕਸਰ (indexer) ਮੁੱਲ ਨੂੰ ਅੱਪਡੇਟ ਕਰਨ ਲਈ ਬਿਲਕੁਲ ਉਹੀ ਕੰਮ ਦੁਬਾਰਾ ਕਰਦਾ ਹੈ। ਤੁਸੀਂ ਪ੍ਰਤੀ ਟੋਕਨ ਇੱਕੋ ਕੀ ਅਤੇ ਇੱਕੋ ਹੈਸ਼ 'ਤੇ ਦੋ ਵਾਰ CPU ਸਾਈਕਲ ਬਰਬਾਦ ਕਰਦੇ ਹੋ।
ਤੁਸੀਂ ਦੂਜੀ ਵਾਰੀ ਨੂੰ ਛੱਡ ਸਕਦੇ ਹੋ। CollectionsMarshal.GetValueRefOrAddDefault ਦੀ ਵਰਤੋਂ ਕਰੋ।
ref int slot = ref CollectionsMarshal.GetValueRefOrAddDefault(counts, code, out _);
slot++;
ਇਹ ਵਿਧੀ ਇੱਕ ਹੀ ਕਦਮ ਵਿੱਚ ਸਲਾਟ (slot) ਲੱਭਦੀ ਹੈ ਜਾਂ ਬਣਾਉਂਦੀ ਹੈ। ਇਹ ਤੁਹਾਨੂੰ ਸਿੱਧਾ ਸਟੋਰੇਜ (storage) ਦਾ ਰੈਫਰੈਂਸ (reference) ਦਿੰਦੀ ਹੈ। ਤੁਸੀਂ ਇੱਕ ਹੈਸ਼ ਅਤੇ ਇੱਕ ਬੱਕਟ ਵਾਕ (bucket walk) ਕਰਦੇ ਹੋ। ਫਿਰ ਤੁਸੀਂ ਮੁੱਲ ਨੂੰ ਉੱਥੇ ਹੀ ਬਦਲ ਦਿੰਦੇ ਹੋ।
ਮੈਂ ਇਸਦਾ 5 ਮਿਲੀਅਨ ਟੋਕਨਾਂ ਨਾਲ ਟੈਸਟ ਕੀਤਾ।
ਨਤੀਜੇ:
• TryGetValue + indexer: 160.0 ms
• GetValueRefOrAddDefault: 95.0 ms
ਇੱਕ-ਲੁੱਕਅੱਪ (one-lookup) ਵਾਲਾ ਵਰਜ਼ਨ 1.7x ਤੇਜ਼ ਹੈ।
ਮਹੱਤਵਪੂਰਨ ਗੱਲ ਇਹ ਹੈ ਕਿ ਮੈਮੋਰੀ ਅਲੋਕੇਸ਼ਨ (memory allocations) ਬਿਲਕੁਲ ਉਹੀ ਰਹੀ। ਇਹ ਤਰੀਕਾ ਮੈਮੋਰੀ ਨਹੀਂ ਬਚਾਉਂਦਾ। ਇਹ ਸਿਰਫ਼ CPU ਬਚਾਉਂਦਾ ਹੈ। ਜੇਕਰ ਤੁਹਾਡਾ ਕੋਡ ਗਾਰਬੇਜ ਕਲੈਕਸ਼ਨ (garbage collection) ਕਾਰਨ ਹੌਲੀ ਹੈ, ਤਾਂ ਇਸ ਬਦਲਾਅ ਨਾਲ ਕੁਝ ਨਹੀਂ ਹੋਵੇਗਾ। ਜੇਕਰ ਤੁਹਾਡਾ ਕੋਡ ਭਾਰੀ ਗਿਣਤੀ (heavy counting) ਕਾਰਨ ਹੌਲੀ ਹੈ, ਤਾਂ ਇਹ ਮਦਦ ਕਰਦਾ ਹੈ।
ਇਸਦੀ ਵਰਤੋਂ ਉਦੋਂ ਕਰੋ ਜਦੋਂ ਤੁਹਾਡਾ ਲੂਪ (loop) ਮੌਜੂਦਾ ਕੀਜ਼ (keys) ਵਿੱਚ ਬਹੁਤ ਸਾਰੇ ਅੱਪਡੇਟ ਕਰਦਾ ਹੈ। ਜਿਵੇਂ-ਜਿਵੇਂ ਇਨਸਰਟ (inserts) ਦੇ ਮੁਕਾਬਲੇ ਅੱਪਡੇਟਸ ਦਾ ਅਨੁਪਾਤ ਵਧਦਾ ਹੈ, ਇਸਦਾ ਫਾਇਦਾ ਵੀ ਵਧਦਾ ਜਾਂਦਾ ਹੈ।
ਇੱਕ ਚੇਤਾਵਨੀ: ਰੈਫਰੈਂਸ ਅੰਦਰੂਨੀ ਡਿਕਸ਼ਨਰੀ ਸਟੋਰੇਜ ਵੱਲ ਇਸ਼ਾਰਾ ਕਰਦਾ ਹੈ। ਇਹ ਸਿਰਫ਼ ਅਗਲੇ ਸੰਰਚਨਾਤਮਕ ਬਦਲਾਅ (structural change) ਤੱਕ ਹੀ ਵੈਧ (valid) ਰਹਿੰਦਾ ਹੈ। ਜੇਕਰ ਤੁਸੀਂ ਕੀਜ਼ (keys) ਜੋੜਦੇ ਜਾਂ ਹਟਾਉਂਦੇ ਹੋ, ਤਾਂ ਰੈਫਰੈਂਸ ਨੂੰ ਫੜ ਕੇ ਨਾ ਰੱਖੋ। ਰੈਫਰੈਂਸ ਲਓ, ਮੁੱਲ ਬਦਲੋ, ਅਤੇ ਅੱਗੇ ਵਧੋ।
ਜ਼ਿਆਦਾਤਰ ਕੰਮਾਂ ਲਈ TryGetValue ਦੀ ਵਰਤੋਂ ਕਰੋ। ਇਹ ਪੜ੍ਹਨ ਵਿੱਚ ਆਸਾਨ ਹੈ। ਰੈਫਰੈਂਸ (ref) ਵਰਜ਼ਨ ਦੀ ਵਰਤੋਂ ਉਦੋਂ ਹੀ ਕਰੋ ਜਦੋਂ ਤੁਹਾਡਾ ਡਿਕਸ਼ਨਰੀ ਲੂਪ ਪਰਫਾਰਮੈਂਸ ਵਿੱਚ ਰੁਕਾਵਟ (bottleneck) ਬਣ ਰਿਹਾ ਹੋਵੇ।
Source: https://dev.to/ssukhpinder/i-hashed-every-word-twice-to-count-it-once-1mg9
