Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Zelfstudie: Hoe u geheugentoewijzingen kunt verminderen met veilig gebruik van
Vaak bestaat het afstemmen van prestaties voor een .NET-toepassing uit twee technieken. Verminder eerst het aantal en de grootte van heap-allocaties. Ten tweede vermindert u hoe vaak gegevens worden gekopieerd. Visual Studio biedt geweldige hulpprogramma's waarmee u kunt analyseren hoe uw toepassing geheugen gebruikt. Zodra u hebt vastgesteld waar uw app onnodige toewijzingen aanbrengt, brengt u wijzigingen aan om deze toewijzingen te minimaliseren. U converteert class typen naar struct typen. U gebruikt refveiligheidsfuncties om semantiek te behouden en extra kopiëren te minimaliseren.
Gebruik Visual Studio 17.5 voor de beste ervaring met deze zelfstudie. Het hulpprogramma voor het toewijzen van .NET-objecten dat wordt gebruikt voor het analyseren van geheugengebruik maakt deel uit van Visual Studio. U kunt Visual Studio Code en de opdrachtregel gebruiken om de toepassing uit te voeren en alle wijzigingen aan te brengen. U kunt de analyseresultaten van uw wijzigingen echter niet zien.
De toepassing die u gaat gebruiken, is een simulatie van een IoT-toepassing die verschillende sensoren bewaakt om te bepalen of een indringer een geheime galerie met waardevolle gegevens heeft ingevoerd. De IoT-sensoren verzenden voortdurend gegevens die de combinatie van Zuurstof (O2) en Koolstofdioxide (CO2) in de lucht meten. Ze rapporteren ook de temperatuur en relatieve vochtigheid. Elk van deze waarden fluctueert de hele tijd enigszins. Wanneer een persoon echter de kamer binnenkomt, verandert de verandering iets meer en altijd in dezelfde richting: Zuurstof neemt af, koolstofdioxide neemt toe, temperatuur neemt toe, net als relatieve vochtigheid. Wanneer de gecombineerde output van de sensoren verhogingen laat zien, wordt het indringeralarm geactiveerd.
In deze zelfstudie voert u de toepassing uit, voert u metingen uit op geheugentoewijzingen en verbetert u de prestaties door het aantal toewijzingen te verminderen. De broncode is beschikbaar in de voorbeeldbrowser.
De starterstoepassing verkennen
Download de toepassing en voer het startersvoorbeeld uit. De startapplicatie werkt correct, maar omdat er bij elke meetcyclus veel kleine objecten worden toegewezen, verslechtert de prestatie langzaam naarmate het na verloop van tijd draait.
Press <return> to start simulation
Debounced measurements:
Temp: 67.332
Humidity: 41.077%
Oxygen: 21.097%
CO2 (ppm): 404.906
Average measurements:
Temp: 67.332
Humidity: 41.077%
Oxygen: 21.097%
CO2 (ppm): 404.906
Debounced measurements:
Temp: 67.349
Humidity: 46.605%
Oxygen: 20.998%
CO2 (ppm): 408.707
Average measurements:
Temp: 67.349
Humidity: 46.605%
Oxygen: 20.998%
CO2 (ppm): 408.707
Veel rijen zijn verwijderd.
Debounced measurements:
Temp: 67.597
Humidity: 46.543%
Oxygen: 19.021%
CO2 (ppm): 429.149
Average measurements:
Temp: 67.568
Humidity: 45.684%
Oxygen: 19.631%
CO2 (ppm): 423.498
Current intruders: 3
Calculated intruder risk: High
Debounced measurements:
Temp: 67.602
Humidity: 46.835%
Oxygen: 19.003%
CO2 (ppm): 429.393
Average measurements:
Temp: 67.568
Humidity: 45.684%
Oxygen: 19.631%
CO2 (ppm): 423.498
Current intruders: 3
Calculated intruder risk: High
U kunt de code verkennen om te leren hoe de toepassing werkt. Het hoofdprogramma voert de simulatie uit. Nadat u op de knop drukt <Enter>, wordt er een ruimte gemaakt en worden enkele initiële basislijngegevens verzameld:
Console.WriteLine("Press <return> to start simulation");
Console.ReadLine();
var room = new Room("gallery");
var r = new Random();
int counter = 0;
room.TakeMeasurements(
m =>
{
Console.WriteLine(room.Debounce);
Console.WriteLine(room.Average);
Console.WriteLine();
counter++;
return counter < 20000;
});
Zodra die basislijngegevens zijn vastgesteld, wordt de simulatie uitgevoerd op de ruimte, waarbij een generator voor willekeurige getallen bepaalt of een indringer de ruimte heeft ingevoerd:
counter = 0;
room.TakeMeasurements(
m =>
{
Console.WriteLine(room.Debounce);
Console.WriteLine(room.Average);
room.Intruders += (room.Intruders, r.Next(5)) switch
{
( > 0, 0) => -1,
( < 3, 1) => 1,
_ => 0
};
Console.WriteLine($"Current intruders: {room.Intruders}");
Console.WriteLine($"Calculated intruder risk: {room.RiskStatus}");
Console.WriteLine();
counter++;
return counter < 200000;
});
Andere typen bevatten de metingen, een gedebouncede meting die het gemiddelde is van de laatste 50 metingen en het gemiddelde van alle genomen metingen.
Voer vervolgens de toepassing uit met behulp van het hulpprogramma .NET-objecttoewijzing. Zorg ervoor dat u de Release build gebruikt, niet de Debug build. Open in het menu Debuggen de Prestatieprofiel. Controleer de optie .NET Objecttoewijzing bijhouden, maar niets anders. Voer uw toepassing uit om deze te voltooien. De profiler meet objecttoewijzingen en rapporteert over toewijzingen en afvalverzamelcycli. U zou een grafiek moeten zien die lijkt op de volgende afbeelding:
In de vorige grafiek ziet u dat het werken om toewijzingen te minimaliseren prestatievoordelen biedt. U ziet een zaagtandpatroon in de grafiek met live-objecten. Dat vertelt u dat er talloze objecten worden gemaakt die snel afval worden. Ze worden later verzameld, zoals weergegeven in de object-deltagrafiek. De rode balken die naar beneden wijzen, geven een afvalverzamelingcyclus aan.
Bekijk vervolgens het tabblad Toewijzingen onder de grafieken. In deze tabel ziet u welke typen het meest worden toegewezen:
Het System.String type is verantwoordelijk voor de meeste toewijzingen. De belangrijkste taak moet zijn om de frequentie van tekenreekstoewijzingen te minimaliseren. Deze toepassing drukt voortdurend talloze opgemaakte uitvoer af op de console. Voor deze simulatie willen we berichten bewaren, dus concentreren we ons op de volgende twee rijen: het SensorMeasurement type en het IntruderRisk type.
Dubbelklik op de SensorMeasurement regel. U kunt zien dat alle toewijzingen plaatsvinden in de static methode SensorMeasurement.TakeMeasurement. U kunt de methode in het volgende codefragment zien:
public static SensorMeasurement TakeMeasurement(string room, int intruders)
{
return new SensorMeasurement
{
CO2 = (CO2Concentration + intruders * 10) + (20 * generator.NextDouble() - 10.0),
O2 = (O2Concentration - intruders * 0.01) + (0.005 * generator.NextDouble() - 0.0025),
Temperature = (TemperatureSetting + intruders * 0.05) + (0.5 * generator.NextDouble() - 0.25),
Humidity = (HumiditySetting + intruders * 0.005) + (0.20 * generator.NextDouble() - 0.10),
Room = room,
TimeRecorded = DateTime.Now
};
}
Elke meting wijst een nieuw SensorMeasurement object toe, een class type. Elke SensorMeasurement die wordt aangemaakt veroorzaakt een heap-toewijzing.
Klassen wijzigen in structs
De volgende code toont de eerste declaratie van SensorMeasurement:
public class SensorMeasurement
{
private static readonly Random generator = new Random();
public static SensorMeasurement TakeMeasurement(string room, int intruders)
{
return new SensorMeasurement
{
CO2 = (CO2Concentration + intruders * 10) + (20 * generator.NextDouble() - 10.0),
O2 = (O2Concentration - intruders * 0.01) + (0.005 * generator.NextDouble() - 0.0025),
Temperature = (TemperatureSetting + intruders * 0.05) + (0.5 * generator.NextDouble() - 0.25),
Humidity = (HumiditySetting + intruders * 0.005) + (0.20 * generator.NextDouble() - 0.10),
Room = room,
TimeRecorded = DateTime.Now
};
}
private const double CO2Concentration = 409.8; // increases with people.
private const double O2Concentration = 0.2100; // decreases
private const double TemperatureSetting = 67.5; // increases
private const double HumiditySetting = 0.4500; // increases
public required double CO2 { get; init; }
public required double O2 { get; init; }
public required double Temperature { get; init; }
public required double Humidity { get; init; }
public required string Room { get; init; }
public required DateTime TimeRecorded { get; init; }
public override string ToString() => $"""
Room: {Room} at {TimeRecorded}:
Temp: {Temperature:F3}
Humidity: {Humidity:P3}
Oxygen: {O2:P3}
CO2 (ppm): {CO2:F3}
""";
}
Het type is oorspronkelijk gemaakt als een class omdat het talloze double metingen bevat. Het is groter dan u wilt kopiëren in dynamische paden. Deze beslissing betekende echter een groot aantal toewijzingen. Wijzig het type van een class in een struct.
Bij het overstappen van een class naar een struct worden er enkele compilerfouten geïntroduceerd, omdat de oorspronkelijke code op een paar plekken null-referentiecontroles gebruikt. De eerste bevindt zich in de DebounceMeasurement klasse, in de AddMeasurement methode:
public void AddMeasurement(SensorMeasurement datum)
{
int index = totalMeasurements % debounceSize;
recentMeasurements[index] = datum;
totalMeasurements++;
double sumCO2 = 0;
double sumO2 = 0;
double sumTemp = 0;
double sumHumidity = 0;
for (int i = 0; i < debounceSize; i++)
{
if (recentMeasurements[i] is not null)
{
sumCO2 += recentMeasurements[i].CO2;
sumO2+= recentMeasurements[i].O2;
sumTemp+= recentMeasurements[i].Temperature;
sumHumidity += recentMeasurements[i].Humidity;
}
}
O2 = sumO2 / ((totalMeasurements > debounceSize) ? debounceSize : totalMeasurements);
CO2 = sumCO2 / ((totalMeasurements > debounceSize) ? debounceSize : totalMeasurements);
Temperature = sumTemp / ((totalMeasurements > debounceSize) ? debounceSize : totalMeasurements);
Humidity = sumHumidity / ((totalMeasurements > debounceSize) ? debounceSize : totalMeasurements);
}
Het DebounceMeasurement type bevat een matrix van 50 metingen. De metingen voor een sensor worden gerapporteerd als het gemiddelde van de laatste 50 metingen. Dat vermindert het geluid in de metingen. Voordat er volledige 50 metingen zijn verricht, zijn deze waarden null. De code controleert op null verwijzing om het juiste gemiddelde te rapporteren bij het opstarten van het systeem. Nadat u het SensorMeasurement type hebt gewijzigd in een struct, moet u een andere test gebruiken. Het SensorMeasurement type bevat een string voor de kameridentificatie, zodat u die test in plaats daarvan kunt gebruiken.
if (recentMeasurements[i].Room is not null)
De andere drie compilerfouten zijn allemaal aanwezig in de methode die herhaaldelijk metingen in een ruimte neemt:
public void TakeMeasurements(Func<SensorMeasurement, bool> MeasurementHandler)
{
SensorMeasurement? measure = default;
do {
measure = SensorMeasurement.TakeMeasurement(Name, Intruders);
Average.AddMeasurement(measure);
Debounce.AddMeasurement(measure);
} while (MeasurementHandler(measure));
}
In de startersmethode is de lokale variabele voor de SensorMeasurement een optionele verwijzing:
SensorMeasurement? measure = default;
Nu het SensorMeasurement een struct in plaats van een classis, is het nullable een type null-waarde. U kunt de declaratie wijzigen in een waardetype om de resterende compilerfouten op te lossen:
SensorMeasurement measure = default;
Nu de compilerfouten zijn opgelost, moet u de code onderzoeken om ervoor te zorgen dat de semantiek niet is gewijzigd. Omdat struct typen worden doorgegeven door waarde, zijn wijzigingen in methodeparameters niet zichtbaar nadat de methode is geretourneerd.
Belangrijk
Als u een type wijzigt van een class naar een struct, kunt u de semantiek van uw programma wijzigen. Wanneer een class type wordt doorgegeven aan een methode, worden alle mutaties die in de methode zijn gemaakt, aan het argument toegevoegd. Wanneer een struct type wordt doorgegeven aan een methode, terwijl mutaties die in de methode zijn gemaakt worden toegepast op een kopie van het argument. Dit betekent dat elke methode die haar argumenten wijzigt, moet worden bijgewerkt om de ref modifier te gebruiken voor elk argumenttype dat u hebt gewijzigd van een class naar een struct.
Het SensorMeasurement type bevat geen methoden die de status wijzigen, dus dat is geen probleem in dit voorbeeld. U kunt dat bewijzen door de readonly modifier toe te voegen aan de SensorMeasurement struct:
public readonly struct SensorMeasurement
De compiler dwingt de readonly aard van de SensorMeasurement struct af. Als uw inspectie van de code een methode mist die de status heeft gewijzigd, zou de compiler u dit vertellen. Uw app bouwt nog steeds zonder fouten, dus dit type is readonly. Door de readonly modifier toe te voegen wanneer u een type wijzigt van een class naar een struct, kunt u leden vinden die de status van de struct wijzigen.
Vermijd het maken van kopieën
U hebt een groot aantal onnodige toewijzingen uit uw app verwijderd. Het SensorMeasurement type wordt nergens in de tabel weergegeven.
Nu gaat het extra werk doen om de SensorMeasurement structuur te kopiëren telkens wanneer deze wordt gebruikt als parameter of een retourwaarde. De SensorMeasurement struct bevat vier doubles, a DateTime en a string. Die structuur is aanzienlijk groter dan een verwijzing. Laten we de ref of in modifiers toevoegen aan plaatsen waar het SensorMeasurement type wordt gebruikt.
De volgende stap is het vinden van methoden die een meting retourneren of een meting als argument uitvoeren en waar mogelijk verwijzingen gebruiken. Begin in de SensorMeasurement structuur. De statische TakeMeasurement methode maakt en retourneert een nieuw SensorMeasurement:
public static SensorMeasurement TakeMeasurement(string room, int intruders)
{
return new SensorMeasurement
{
CO2 = (CO2Concentration + intruders * 10) + (20 * generator.NextDouble() - 10.0),
O2 = (O2Concentration - intruders * 0.01) + (0.005 * generator.NextDouble() - 0.0025),
Temperature = (TemperatureSetting + intruders * 0.05) + (0.5 * generator.NextDouble() - 0.25),
Humidity = (HumiditySetting + intruders * 0.005) + (0.20 * generator.NextDouble() - 0.10),
Room = room,
TimeRecorded = DateTime.Now
};
}
We laten deze als zodanig achter en retourneren per waarde. Als u probeert terug te keren door ref, krijgt u een compilerfout. U kunt geen ref retourneren naar een nieuwe structuur die lokaal in de methode is gemaakt. Het ontwerp van de onveranderbare struct betekent dat u alleen de waarden van de meting bij de bouw kunt instellen. Deze methode moet een nieuwe meetstruct maken.
Laten we eens naar DebounceMeasurement.AddMeasurement kijken. U moet de in wijzigingsfunctie toevoegen aan de measurement parameter:
public void AddMeasurement(in SensorMeasurement datum)
{
int index = totalMeasurements % debounceSize;
recentMeasurements[index] = datum;
totalMeasurements++;
double sumCO2 = 0;
double sumO2 = 0;
double sumTemp = 0;
double sumHumidity = 0;
for (int i = 0; i < debounceSize; i++)
{
if (recentMeasurements[i].Room is not null)
{
sumCO2 += recentMeasurements[i].CO2;
sumO2+= recentMeasurements[i].O2;
sumTemp+= recentMeasurements[i].Temperature;
sumHumidity += recentMeasurements[i].Humidity;
}
}
O2 = sumO2 / ((totalMeasurements > debounceSize) ? debounceSize : totalMeasurements);
CO2 = sumCO2 / ((totalMeasurements > debounceSize) ? debounceSize : totalMeasurements);
Temperature = sumTemp / ((totalMeasurements > debounceSize) ? debounceSize : totalMeasurements);
Humidity = sumHumidity / ((totalMeasurements > debounceSize) ? debounceSize : totalMeasurements);
}
Hiermee wordt één kopieerbewerking opgeslagen. De in parameter is een verwijzing naar de kopie die al door de aanroeper is gemaakt. U kunt ook een kopie opslaan met de TakeMeasurement methode in het Room type. Deze methode illustreert hoe de compiler veiligheid biedt wanneer u argumenten doorgeeft ref. De eerste TakeMeasurement methode in het Room type neemt een argument van Func<SensorMeasurement, bool>. Als u de in of ref wijzigingsfunctie aan die declaratie probeert toe te voegen, meldt de compiler een fout. U kunt geen ref argument doorgeven aan een lambda-expressie. De compiler kan niet garanderen dat de aangeroepen expressie de verwijzing niet kopieert. Als de lambda-expressie de verwijzing vastlegt , kan de verwijzing een levensduur hebben die langer duurt dan de waarde waarnaar wordt verwezen. Toegang tot deze buiten de veilige context van de ref zou leiden tot beschadiging van het geheugen. De ref veiligheidsregels staan het niet toe. Meer informatie vindt u in het overzicht van refveiligheidsfuncties.
Semantiek behouden
De laatste wijzigingenpakketten hebben geen grote invloed op de prestaties van deze toepassing, omdat de types niet in kritieke paden worden gemaakt. Deze wijzigingen illustreren enkele van de andere technieken die u zou gebruiken bij het afstemmen van de prestaties. Laten we eens kijken naar de eerste Room klas:
public class Room
{
public AverageMeasurement Average { get; } = new ();
public DebounceMeasurement Debounce { get; } = new ();
public string Name { get; }
public IntruderRisk RiskStatus
{
get
{
var CO2Variance = (Debounce.CO2 - Average.CO2) > 10.0 / 4;
var O2Variance = (Average.O2 - Debounce.O2) > 0.005 / 4.0;
var TempVariance = (Debounce.Temperature - Average.Temperature) > 0.05 / 4.0;
var HumidityVariance = (Debounce.Humidity - Average.Humidity) > 0.20 / 4;
IntruderRisk risk = IntruderRisk.None;
if (CO2Variance) { risk++; }
if (O2Variance) { risk++; }
if (TempVariance) { risk++; }
if (HumidityVariance) { risk++; }
return risk;
}
}
public int Intruders { get; set; }
public Room(string name)
{
Name = name;
}
public void TakeMeasurements(Func<SensorMeasurement, bool> MeasurementHandler)
{
SensorMeasurement? measure = default;
do {
measure = SensorMeasurement.TakeMeasurement(Name, Intruders);
Average.AddMeasurement(measure);
Debounce.AddMeasurement(measure);
} while (MeasurementHandler(measure));
}
}
Dit type bevat verschillende eigenschappen. Sommige zijn class typen. Het maken van een Room object omvat meerdere toewijzingen. Eén voor zichzelf Room en één voor elk van de leden van een class type dat het bevat. U kunt twee van deze eigenschappen converteren van class typen naar struct typen: de DebounceMeasurement en AverageMeasurement typen. Laten we die transformatie met beide typen doorlopen.
Wijzig het DebounceMeasurement type van een class in struct. Hiermee wordt een compilerfout CS8983: A 'struct' with field initializers must include an explicitly declared constructorgeïntroduceerd. U kunt dit oplossen door een lege parameterloze constructor toe te voegen:
public DebounceMeasurement() { }
U kunt meer leren over deze vereiste in het taalreferentiedocument over structs.
De Object.ToString() overschrijving wijzigt geen van de waarden van de struct. U kunt de readonly wijzigingsfunctie toevoegen aan die methodedeclaratie. Het DebounceMeasurement type is muteerbaar, dus u moet ervoor zorgen dat wijzigingen geen invloed hebben op kopieën die verloren gaan. De AddMeasurement methode wijzigt de status van het object. Het wordt aangeroepen vanuit de Room klasse, in de TakeMeasurements methode. U wilt dat deze wijzigingen behouden blijven nadat u de methode hebt aangeroepen. U kunt de Room.Debounce eigenschap wijzigen om een verwijzing naar één exemplaar van het DebounceMeasurement type te retourneren:
private DebounceMeasurement debounce = new();
public ref readonly DebounceMeasurement Debounce { get { return ref debounce; } }
In het vorige voorbeeld zijn enkele wijzigingen aangebracht. Ten eerste is de eigenschap een alleen-lezen eigenschap die een alleen-lezen verwijzing retourneert naar het exemplaar dat eigendom is van deze ruimte. Het wordt nu ondersteund door een gedeclareerd veld dat wordt geïnitialiseerd wanneer het Room object wordt geïnstantieerd. Nadat u deze wijzigingen hebt aangebracht, werkt u de implementatie van AddMeasurement de methode bij. Het maakt gebruik van het privé-backingveld, debounce, niet van de alleen-lezen eigenschap Debounce. Op die manier vinden de wijzigingen plaats op het enkele exemplaar dat tijdens de initialisatie is gemaakt.
Dezelfde techniek werkt met de Average eigenschap. Eerst wijzigt u het AverageMeasurement type van een class in een structen voegt u de readonly wijzigingsfunctie toe aan de ToString methode:
namespace IntruderAlert;
public struct AverageMeasurement
{
private double sumCO2 = 0;
private double sumO2 = 0;
private double sumTemperature = 0;
private double sumHumidity = 0;
private int totalMeasurements = 0;
public AverageMeasurement() { }
public readonly double CO2 => sumCO2 / totalMeasurements;
public readonly double O2 => sumO2 / totalMeasurements;
public readonly double Temperature => sumTemperature / totalMeasurements;
public readonly double Humidity => sumHumidity / totalMeasurements;
public void AddMeasurement(in SensorMeasurement datum)
{
totalMeasurements++;
sumCO2 += datum.CO2;
sumO2 += datum.O2;
sumTemperature += datum.Temperature;
sumHumidity+= datum.Humidity;
}
public readonly override string ToString() => $"""
Average measurements:
Temp: {Temperature:F3}
Humidity: {Humidity:P3}
Oxygen: {O2:P3}
CO2 (ppm): {CO2:F3}
""";
}
Vervolgens wijzigt u de Room klasse volgens dezelfde techniek die u voor de Debounce eigenschap hebt gebruikt. De Average eigenschap retourneert een readonly ref naar het privéveld voor de gemiddelde meting. De AddMeasurement methode wijzigt de interne velden.
private AverageMeasurement average = new();
public ref readonly AverageMeasurement Average { get { return ref average; } }
Voorkom boksen
Er is één laatste wijziging om de prestaties te verbeteren. Het belangrijkste programma is het afdrukken van statistieken voor de ruimte, met inbegrip van de risicoanalyse:
Console.WriteLine($"Current intruders: {room.Intruders}");
Console.WriteLine($"Calculated intruder risk: {room.RiskStatus}");
De aanroep van de gegenereerde ToString omsluit de opsommingswaarde. U kunt dit voorkomen door een override te schrijven in de Room class waarmee de tekenreeks wordt opgemaakt op basis van de waarde van het geschatte risico.
public override string ToString() =>
$"Calculated intruder risk: {RiskStatus switch
{
IntruderRisk.None => "None",
IntruderRisk.Low => "Low",
IntruderRisk.Medium => "Medium",
IntruderRisk.High => "High",
IntruderRisk.Extreme => "Extreme",
_ => "Error!"
}}, Current intruders: {Intruders.ToString()}";
Wijzig vervolgens de code in het hoofdprogramma om deze nieuwe ToString methode aan te roepen:
Console.WriteLine(room.ToString());
Voer de app uit met behulp van de profiler en bekijk de bijgewerkte tabel voor toewijzingen.
U hebt talloze toewijzingen verwijderd en uw app voorzien van een prestatieverbetering.
Ref-veiligheid gebruiken in uw toepassing
Deze technieken zijn het afstemmen van prestaties op laag niveau. Ze kunnen de prestaties in uw toepassing verbeteren wanneer ze worden toegepast op dynamische paden en wanneer u de impact voor en na de wijzigingen hebt gemeten. In de meeste gevallen is de cyclus die u volgt:
- Allocaties meten: bepaal welke typen allocaties het meest worden toegewezen en wanneer u de heap-allocaties kunt verminderen.
-
Klasse converteren naar struct: Vaak kunnen typen worden geconverteerd van een
classnaar eenstruct. Uw app maakt gebruik van stackruimte in plaats van heap-toewijzingen te maken. -
Semantiek behouden: het converteren van een
classnaar eenstructkan van invloed zijn op de semantiek voor parameters en retourwaarden. Elke methode die de parameters wijzigt, moet deze parameters nu markeren met derefwijzigingsfunctie. Dit zorgt ervoor dat de wijzigingen aan het juiste object worden aangebracht. Als een eigenschap of methode-retourwaarde door de aanroeper moet worden gewijzigd, moet die retourwaarde worden gemarkeerd met derefmodificeerder. -
Vermijd kopieën: wanneer u een grote struct als parameter doorgeeft, kunt u de parameter markeren met de
inwijzigingsfunctie. U kunt een verwijzing doorgeven in minder bytes en ervoor zorgen dat de methode de oorspronkelijke waarde niet wijzigt. U kunt ook waarden retourneren doorreadonly refeen verwijzing te retourneren die niet kan worden gewijzigd.
Met deze technieken kunt u de prestaties in dynamische paden van uw code verbeteren.