Page 1 of 1

Das Hinzufügen einer Attributeuse in einem benutzerdefinierten Attribut verdoppelt die Zeit, die benötigt wird, um einen

Posted: 09 Apr 2025, 04:28
by Anonymous
Kommentar [Attributeusage (AttributTargets.Property | AttractReTargets.field, erlaubte Multiple = false)] Auf einem Attribut meine Deserialisierungsklasse verwendet Hälften, wie viel Zeit, die es benötigt, eine Datentatable in eine Liste meiner Klasse übersetzen. Unten finden Sie die Mindestmenge an Code, um das Problem zu reproduzieren: < /p>
Hier ist das Attribut: < /p>
internal enum MODIFIERS { TRIM, TOUPPER, TOLOWER}
//RUN ONCE, THEN COMMENT OUT THIS NEXT LINE AND COMPARE THE RUNTIMES.
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
internal class InstructionAttribute : Attribute
{
public MODIFIERS[] INSTRUCTIONS;
internal InstructionAttribute(params MODIFIERS[] INSTRUCTIONS)
{
if (INSTRUCTIONS.Contains(MODIFIERS.TOUPPER) && INSTRUCTIONS.Contains(MODIFIERS.TOLOWER))
throw new Exception("sigh");
this.INSTRUCTIONS = INSTRUCTIONS;
}
}
< /code>
Hier ist die Klasse, mit der sie verwendet wird: < /p>
internal class Pets
{
public string Dog1 { get; set; }
public string Dog2 { get; set; }
public string Cat1 { get; set; }
public string Cat2 { get; set; }

[Instruction(MODIFIERS.TOUPPER, MODIFIERS.TRIM)]
public string Snek { get; set; }
}
< /code>
Hier ist Code, um das Problem zu reproduzieren: < /p>
DataTable dt = new DataTable();
dt.Columns.Add("Dog1");
dt.Columns.Add("Dog2");
dt.Columns.Add("Cat1");
dt.Columns.Add("Cat2");
dt.Columns.Add("Snek");
for (int i = 0; i < 500000; i++)
{
var row = dt.NewRow();
row["Dog1"] = "Amos";
row["Dog2"] = "Holden";
row["Cat1"] = "Chisjen";
row["Cat2"] = "Naomi";
row["Snek"] = "Dawes";
dt.Rows.Add(row);
}
var sw = Stopwatch.StartNew();
var props = typeof(Pets).GetProperties().ToDictionary(k => k.Name, v=>v);
List pets = new List();
foreach (DataRow row in dt.AsEnumerable())
{
Pets p = new Pets();
foreach (DataColumn column in dt.Columns)
{
string valueToSave = row[column.ColumnName].ToString();
if (Attribute.IsDefined(props[column.ColumnName], typeof(InstructionAttribute)))
{
var attr = (InstructionAttribute)props[column.ColumnName].GetCustomAttribute(typeof(InstructionAttribute));
if(attr.INSTRUCTIONS.Contains(MODIFIERS.TRIM))
valueToSave = valueToSave.Trim();
if (attr.INSTRUCTIONS.Contains(MODIFIERS.TOUPPER))
valueToSave = valueToSave.ToUpper();
if (attr.INSTRUCTIONS.Contains(MODIFIERS.TOLOWER))
valueToSave = valueToSave.ToLower();
}
props[column.ColumnName].SetValue(p, valueToSave);
}
pets.Add(p);
}
Console.WriteLine($"Time Taken: {sw.ElapsedMilliseconds}ms");
< /code>
Das Attribut.ISDEFIDED ist das, was die erhöhte Zeitverbindung verursacht, aber ich verstehe nicht, warum. Ich nahm an, dass die Attributnutzungs -Tags zum Kompilierungszeit verwendet wurden, damit sie Probleme erfassen können, bevor der Code ausgeführt wird ... aber es scheint zur Laufzeit etwas zu tun.>