Lag when updating large amounts of objects

Hello! Working on an atmospherics simulator for a tile-based game. If a tile has a “leak” (either missing a diagonal/adjacent wall or floor tile), it drains the “oxygen level” of that tile (a float). I’m updating these values every five seconds based on the average of the values of all adjacent tiles. Unfortunately, I’m getting a lag spike every time it updates these values. Currently, I’m only trying to update a 9x9 grid of tiles (81 total) with one “leak” at one corner. The goal I’m trying to achieve works beautifully, it’s just lag that’s the issue at this point.

Two-part question for you all…

  1. Is there any general procedure/guidelines to follow when updating large amounts of objects.
  2. Is there anything specifically you could recommend for this script that would alleviate the lag issues?

Thanks in advance!

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class AtmosPropagation : MonoBehaviour {
	Collider[] adjacentObjects;
	List<GameObject> adjacentTiles;
	List<GameObject> adjacentWalls;
	public float oxygen;
	float averageOxygen = 0f;
	bool leak = false;
	// Use this for initialization
	void Start () {
		adjacentTiles = new List<GameObject>();
		adjacentWalls = new List<GameObject>();
		adjacentObjects = Physics.OverlapSphere(transform.position, 1.5f);
		if(adjacentObjects.Length == 0)
			Debug.Log ("NO COLLISION!");
		foreach(Collider col in adjacentObjects){
			if(col.gameObject.tag == "Floor"){
				adjacentTiles.Add(col.gameObject);
			} else if(col.gameObject.tag == "Wall"){
				adjacentWalls.Add(col.gameObject);
			}
		}
		oxygen = 20f;
		
		// [START ATMOS SIMULATION]
		InvokeRepeating("PropagateAtmos", 5.0f, 5.0f);
	}
	
	// Update is called once per frame
	void Update () {
		
	}
	
	public void PropagateAtmos(){
		CheckForLeaks();
		foreach(GameObject go in adjacentTiles){
			averageOxygen += go.GetComponent<AtmosPropagation>().oxygen;
		}
		if(leak == false)
			oxygen = averageOxygen / adjacentTiles.Count;
		//yield return new WaitForSeconds(5f);
		Debug.Log("Oxygen Level of Tile @ " + transform.position.ToString() + " = " + oxygen);
		averageOxygen = 0f;
		
		if(oxygen >= 18f)
			renderer.material.color = Color.green;
		if(oxygen >= 15f && oxygen < 18f)
			renderer.material.color = Color.yellow;
		if(oxygen > 10f && oxygen < 15f)
			renderer.material.color = Color.red;
		if(oxygen <= 10f)
			renderer.material.color = Color.black;
	}
	
	public void CheckForLeaks(){
		if((adjacentTiles.Count + adjacentWalls.Count) < 10){
			leak = true;
			Debug.Log ("Walls: " + adjacentWalls.Count);
			if(oxygen < 0)
				oxygen = 0;
			if(oxygen != 0)
				oxygen -= (oxygen * .1f);
		}
	}
}

Edit: To clarify, this script is on each of my “floor” tiles.

go.GetComponent().oxygen;

store the component so you stop fetching it constantly.

try breaking up the update, don’t update them all at the same time, chain the updates.

all you need to do is have the start value of invoke repeating the first 5. be a random number that is 4.5 + a random value between .1 and .5;

if you have it be .1 or .2 or .3 or .4 or .5 you’ll now update them 1/5th each time. (approx of course, its random but on average they should be distributed with 1/5th in each of the five areas given a sufficiently large amount of calls to random)
and honestly frames are over faster than 1/10th of a second, normally closer to a 30th of a second. but just for now have that. You’ll get 1/5th as much updating happening in the same frame. that should help remove the hiccuping.