how to check which constraints would be violated by a presumed solution? - choco

In some cases the solver fails to find a solution for my model, which I think is there.
So I would like to populate a solution, and then check which constraint is violated.
How to do that with choco-solver?
Using choco-solver 4.10.6.

Forcing a solution
I ended up adding constraints to force variables to values of my presumed solution:
e.g.
// constraints to force given solution
vehicle2FirstStop[0].eq(model.intVar(4)).post();
vehicle2FirstStop[1].eq(model.intVar(3)).post();
nextStop[1].eq(model.intVar(0)).post();
nextStop[2].eq(model.intVar(1)).post();
...
and then
model.getSolver().showContradiction();
if (model.getSolver().solve()) { ....
Shows the first contradiction of the presumed solution, e.g.
/!\ CONTRADICTION (PropXplusYeqZ(sum_exp_49, mul_exp_51, ...
So the next step is to find out where terms such as sum_exp_49 come from.
Matching the contradiction terms with the code
Here is a simple fix for constraints which will hopefully provide enough information. We can override the post() and associates() methods of model, so that it dumps the java source filename and line number when a constraint is posted/variable is created.
Model model = new Model("Vrp1RpV") {
/**
* retrieve the filename and line number of first caller outside of choco-solver from stacktrace
*/
String getSource() {
String source = null;
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
// starts from 3: thread.getStackTrace() + this.getSource() + caller (post() or associates())
for (int i = 3; i < stackTraceElements.length; i++) {
// keep rewinding until we get out of choco-solver packages
if (!stackTraceElements[i].getClassName().toString().startsWith("org.chocosolver")) {
source = stackTraceElements[i].getFileName() + ":" + stackTraceElements[i].getLineNumber();
break;
}
}
return source;
}
#Override
public void post(Constraint... cs) throws SolverException {
String source=getSource();
// dump each constraint along source location
for (Constraint c : cs) {
System.err.println(source + " post: " + c);
}
super.post(cs);
}
#Override
public void associates(Variable variable) {
System.err.println(getSource() + " associates: " + variable.getName());
super.associates(variable);
}
};
This will dump things like:
Vrp1RpV2.java:182 post: ARITHM ([prop(EQ_exp_47.EQ.mul_exp_48)])
Vrp1RpV2.java:182 associates: sum_exp_49
Vrp1RpV2.java:182 post: ARITHM ([prop(mul_exp_48.EQ.sum_exp_49)])
Vrp1RpV2.java:182 associates: EQ_exp_50
Vrp1RpV2.java:182 post: BASIC_REIF ([(stop2vehicle[2] = 1) <=> EQ_exp_50])
...
From there it is possible to see where sum_exp_49 comes from.
EDIT: added associates() thanks to #cprudhom suggestion on https://gitter.im/chocoteam/choco-solver

Related

Is it possible in Mono.Cecil to determine the actual type of an object on which a method is called?

For example, consider the following C# code:
interface IBase { void f(int); }
interface IDerived : IBase { /* inherits f from IBase */ }
...
void SomeFunction()
{
IDerived o = ...;
o.f(5);
}
I know how to get a MethodDefinition object corresponding to SomeFunction.
I can then loop through MethodDefinition.Instructions:
var methodDef = GetMethodDefinitionOfSomeFunction();
foreach (var instruction in methodDef.Body.Instructions)
{
switch (instruction.Operand)
{
case MethodReference mr:
...
break;
}
yield return memberRef;
}
And this way I can find out that the method SomeFunction calls the function IBase.f
Now I would like to know the declared type of the object on which the function f is called, i.e. the declared type of o.
Inspecting mr.DeclaringType does not help, because it returns IBase.
This is what I have so far:
TypeReference typeRef = null;
if (instruction.OpCode == OpCodes.Callvirt)
{
// Identify the type of the object on which the call is being made.
var objInstruction = instruction;
if (instruction.Previous.OpCode == OpCodes.Tail)
{
objInstruction = instruction.Previous;
}
for (int i = mr.Parameters.Count; i >= 0; --i)
{
objInstruction = objInstruction.Previous;
}
if (objInstruction.OpCode == OpCodes.Ldloc_0 ||
objInstruction.OpCode == OpCodes.Ldloc_1 ||
objInstruction.OpCode == OpCodes.Ldloc_2 ||
objInstruction.OpCode == OpCodes.Ldloc_3)
{
var localIndex = objInstruction.OpCode.Op2 - OpCodes.Ldloc_0.Op2;
typeRef = locals[localIndex].VariableType;
}
else
{
switch (objInstruction.Operand)
{
case FieldDefinition fd:
typeRef = fd.DeclaringType;
break;
case VariableDefinition vd:
typeRef = vd.VariableType;
break;
}
}
}
where locals is methodDef.Body.Variables
But this is, of course, not enough, because the arguments to a function can be calls to other functions, like in f(g("hello")). It looks like the case above where I inspect previous instructions must repeat the actions of the virtual machine when it actually executes the code. I do not execute it, of course, but I need to recognize function calls and replace them and their arguments with their respective returns (even if placeholders). It looks like a major pain.
Is there a simpler way? Maybe there is something built-in already?
I am not aware of an easy way to achieve this.
The "easiest" way I can think of is to walk the stack and find where the reference used as the target of the call is pushed.
Basically, starting from the call instruction go back one instruction at a time taking into account how each one affects the stack; this way you can find the exact instruction that pushes the reference used as the target of the call (a long time ago I wrote something like that; you can use the code at https://github.com/lytico/db4o/blob/master/db4o.net/Db4oTool/Db4oTool/Core/StackAnalyzer.cs as inspiration).
You'll need also to consider scenarios in which the pushed reference is produced through a method/property; for example, SomeFunction().f(5). In this case you may need to evaluate that method to find out the actual type returned.
Keep in mind that you'll need to handle a lot of different cases; for example, imagine the code bellow:
class Utils
{
public static T Instantiate<T>() where T : new() => new T();
}
class SomeType
{
public void F(int i) {}
}
class Usage
{
static void Main()
{
var o = Utils.Instantiate<SomeType>();
o.F(1);
}
}
while walking the stack you'll find that o is the target of the method call; then you'll evaluate Instantiate<T>() method and will find that it returns new T() and knowing that T is SomeType in this case, that is the type you're looking for.
So the answer of Vagaus helped me come up with a working implementation.
I published it on github - https://github.com/MarkKharitonov/MonoCecilExtensions
Included many unit tests, but I am sure I missed some cases.

Eclipse JDT resolve unknown kind from annotation IMemberValuePair

I need to retrieve the value from an annotation such as this one that uses a string constant:
#Component(property = Constants.SERVICE_RANKING + ":Integer=10")
public class NyServiceImpl implements MyService {
But I am getting a kind of K_UNKNOWN and the doc says "the value is an expression that would need to be further analyzed to determine its kind". My question then is how do I perform this analysis? I could even manage to accept getting the plain source text value in this case.
The other answer looks basically OK, but let me suggest a way to avoid using the internal class org.eclipse.jdt.internal.core.Annotation and its method findNode():
ISourceRange range = annotation.getSourceRange();
ASTNode annNode = org.eclipse.jdt.core.dom.NodeFinder.perform(cu, range);
From here on you should be safe, using DOM API throughout.
Googling differently I found a way to resolve the expression. Still open to other suggestions if any. For those who might be interested, here is a snippet of code:
if (valueKind == IMemberValuePair.K_UNKNOWN) {
Annotation ann = (Annotation)annotation;
CompilationUnit cu = getAST(ann.getCompilationUnit());
ASTNode annNode = ann.findNode(cu);
NormalAnnotation na = (NormalAnnotation)annNode;
List<?> naValues = na.values();
Optional<?> optMvp = naValues.stream()
.filter(val-> ((MemberValuePair)val).getName().getIdentifier().equals(PROPERTY))
.findAny();
if (optMvp.isPresent()) {
MemberValuePair pair = (MemberValuePair)optMvp.get();
if (pair.getValue() instanceof ArrayInitializer) {
ArrayInitializer ai = (ArrayInitializer)pair.getValue();
for (Object exprObj : ai.expressions()) {
Expression expr = (Expression)exprObj;
String propValue = (String)expr.resolveConstantExpressionValue();
if (propValue.startsWith(Constants.SERVICE_RANKING)) {
return true;
}
}
}
else {
Expression expr = pair.getValue();
String propValue = (String)expr.resolveConstantExpressionValue();
if (propValue.startsWith(Constants.SERVICE_RANKING)) {
return true;
}
}
}
//report error
}
private CompilationUnit getAST(ICompilationUnit compUnit) {
final ASTParser parser = ASTParser.newParser(AST.JLS8);
parser.setKind(ASTParser.K_COMPILATION_UNIT);
parser.setSource(compUnit);
parser.setResolveBindings(true); // we need bindings later on
CompilationUnit unit = (CompilationUnit)parser.createAST(null);
return unit;
}

Get the most possible token types according to line and column number in ANTLR4

I would like to get a list of most possible list of tokens for a given location in the text (line and column number) to determine what has to be populated for auto code completion. Can this be easily achieved using ANTLR 4 API.
I want to get the possible list of tokens for a given location because the user might be writing/editing somewhere in the middle of the text which still guarantees the possible list of tokens.
Please give me some guidelines because I was unable to find an online resource on this topic.
One way to get tokens by line number is to create a ParseTreeListener for your grammar, use it to walk a given ParseTree and index TerminalNodes by line number. I don't know C#, but here is how I've done it in Java. Logic should be similar.
public class MyLineIndexer extends MyGrammarParserBaseListener {
protected MultiMap<Integer, TerminalNode> filelineTokenIndex;
#Override
public void visitTerminal(#NotNull TerminalNode node) {
// map every token to its file line for searching later...
if ( node.getSymbol() != null ) {
List<TerminalNode> tokens;
Integer line = node.getSymbol().getLine();
if (!filelineTokenIndex.containsKey(line)) {
tokens = new ArrayList<>();
filelineTokenIndex.put(line, tokens);
} else {
tokens = filelineTokenIndex.get(line);
}
tokens.add(node);
}
super.visitTerminal(node);
}
}
then walk the parse tree the usual way...
ParseTree parseTree = ... ; // parse it how you want to
MyLineIndexer indexer = new MyLineIndexer();
ParseTreeWalker walker = new ParseTreeWalker();
walker.walk(indexer, parseTree);
Getting the token at a line and range is now reasonably straight forward and efficient assuming you have a reasonable number of tokens on a line. For example you can add another method to the Listener like this:
public TerminalNode findTerminalNodeAtCaret(int caretPos, int caretLine) {
if (caretPos <= 0) return null;
if (this.filelineTokenIndex.containsKey(caretLine)) {
List<TerminalNode> nodes = filelineTokenIndex.get(caretLine);
if (nodes.size() == 0) return null;
int tokenEndPos, tokenStartPos;
for (TerminalNode n : nodes) {
if (n.getSymbol() != null) {
tokenEndPos = n.getSymbol().getCharPositionInLine() + n.getText().length();
tokenStartPos = n.getSymbol().getCharPositionInLine();
// If the caret is within this token, return this token
if (caretPos >= tokenStartPos && caretPos <= tokenEndPos) {
return n;
}
}
}
}
return null;
}
You will also need to ensure your parser allows for 'loose' parsing. While a language construct is being typed, it is likely not to be valid. Your Parser rules should allow for this.

Automate Resharper's "to property with backing field" across many properties and classes?

I've got some C# code like this (class file = Status.cs):
/// <summary>
/// Constructs a status entity with the text specified
/// </summary>
/// <param name="someParameter">Some parameter.</param>
public Status(string someParameter)
{
SomeProperty = someParameter;
}
/// <summary>
/// An example of a virtual property.
/// </summary>
public virtual string SomeProperty { get; private set; }
And I want to do 3 things to it:
perform a Resharper "to property with backing field" on it
get rid of the "private set" and replace it with a regular "set"
change the constructor so it initializes the private field instead of the property
So the end result would look like this:
/// <summary>
/// Constructs a status entity with the text specified
/// </summary>
/// <param name="someParameter">Some parameter.</param>
public Status(string someParameter)
{
_someProperty = someParameter;
}
private string _someProperty;
/// <summary>
/// An example of a virtual property.
/// </summary>
public virtual string SomeProperty
{
get { return _someProperty; }
set { _someProperty = value; }
}
And my question is: Is there a way to automate this type of refactoring using, say, the Resharper API ?
Background:
For those who might wonder why I want to do this, it's because:
I'm upgrading NHibernate (old=2.1.2.4000, new=3.3.1.4000) and Fluent NHibernate (old=1.1.0.685, new=1.3.0.0).
I've got rid of the old NHibernate.ByteCode.Castle.dll and the corresponding line in the config file, so I can now use the default proxy that's built into the latest NHibernate.
Between the new implementation of NHibernate and the new version of Fluent, there seem to be two problems when I try to build and run unit tests (part of this is FxCop complaining, but anyway):
a) exceptions are thrown because of the "private set", and
b) exceptions are thrown because the virtual property is being initialized in the constructor.
So I found that if I make those changes, it compiles and the unit tests pass.
So that's fine for a class or two, but there are over 800 class files and who knows how many properties.
I'm sure there are lots of ways to do this (e.g. using reflection, recursing through the directories and parsing the files etc), but it seems like Resharper is the proper tool for something like this.
Any help appreciated, thank you, -Dave
--In response to the answer saying "just change it to a protected set and you're done":
Unfortunately it’s not that simple.
Here is the error that occurs on running unit tests (before making any changes to any class):
Test method threw exception:
NHibernate.InvalidProxyTypeException: The following types may not be used as proxies:
.Status: method set_StatusText should be 'public/protected virtual' or 'protected internal virtual'
..Status: method set_Location should be 'public/protected virtual' or 'protected internal virtual'
So if I change the class as suggested (where the only change is to change the “private set” to a “protected set”), the project will not build, because:
Error 2 CA2214 : Microsoft.Usage : 'Status.Status(string, StatusLocation)' contains a call chain that results in a call to a virtual method defined by the class. Review the following call stack for unintended consequences:
Status..ctor(String, StatusLocation)
Status.set_Location(StatusLocation):Void C:\\Status.cs 28
That is why it is also necessary to change any statement in the constructor which initializes one of these virtual properties.
The previous implementation of the NHibernate proxy (ByteCode.Castle) did not seem to care about the “private set”, whereas this one does.
And, admittedly, the second error is because of FxCop, and I could just put an attribute on the class to tell FxCop not to complain about this, but that seems to just be making the problem go away, and initializing virtual properties in constructors is, as I understand it, bad practice anyway.
So my question still stands. The changes I initially described are the changes I would like to make. How can I automate these changes?
I went ahead and wrote a C# utility to parse such a class file. The "protected set" idea is valid to a point (thanks Hazzik), but it still needs a backing field. The below code produces the output I described above (except uses a "protected set"). Regards, -Dave
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace ConsoleApplication3
{
// TODO: write recursive algorithm to loop through directories
// TODO: handle generic collections as Fluent NHibernate treats those differently
class Program
{
public static string ConvertInitialCapitalToUnderscoreAndLowerCase(string input)
{
var firstChar = input.Substring(0, 1);
var restOfStmt = input.Substring(1);
var newFirst = "_" + firstChar.ToLower();
var output = newFirst + restOfStmt;
return output;
}
// this gets any tabs or spaces at the beginning of the line of code as a string,
// so as to preserve the indentation (and/or add deeper levels of indentation)
public static string GetCodeLineIndentation(string input)
{
var charArray = input.ToCharArray();
var sbPrefix = new StringBuilder();
foreach (var c in charArray)
{
// if it's a tab or a space, add it to the "prefix"
if (c == 9 || c == ' ')
{
sbPrefix.Append(c);
}
else
{
// get out as soon as we hit the first ascii character (those with a value up to 127)
break;
}
}
return sbPrefix.ToString();
}
static void Main(string[] args)
{
const string path = #"C:\pathToFile\Status.cs";
Console.WriteLine("Examining file: " + path);
if (!File.Exists(path))
{
Console.WriteLine("File does not exist: " + path);
throw new FileNotFoundException(path);
}
// Read the file.
var arrayOfLines = File.ReadAllLines(path);
// Convert to List<string>
var inputFileAsListOfStrings = new List<string>(arrayOfLines);
// See if there are any virtual properties.
var virtualProps = inputFileAsListOfStrings.Where(s => s.Contains("public virtual")).ToList();
// See if there are any "private set" strings.
var privateSets = inputFileAsListOfStrings.Where(s => s.Contains("private set")).ToList();
if (virtualProps.Count > 0)
{
Console.WriteLine("Found " + virtualProps.Count + " virtual properties in the class...");
}
if (privateSets.Count > 0)
{
Console.WriteLine("Found " + privateSets.Count + " private set statements in the class...");
}
// Get a list of names of the virtual properties
// (the 4th "word", i.e. index = 3, in the string, will be the property name,
// e.g. "public virtual string SomePropertyName"
var virtualPropNames = virtualProps.Select(vp => vp.Trim().Split(' ')).Select(words => words[3]).ToList();
if (virtualPropNames.Count() != virtualProps.Count())
{
throw new Exception("Error: the list of virtual property names does not equal the number of virtual property statements!");
}
// Find all instances of the virtual properties being initialized.
// By examining the overall file for instances of the virtual property name followed by an equal sign,
// we can identify those lines which are statements initializing the virtual property.
var initializeStatements = (from vpName in virtualPropNames
from stmt in inputFileAsListOfStrings
let stmtNoSpaces = stmt.Trim().Replace(" ", "")
where stmtNoSpaces.StartsWith(vpName + "=")
select stmt).ToList();
if (initializeStatements.Count() > 0)
{
Console.WriteLine("Found " + initializeStatements.Count + " initialize statements in the class...");
}
// now process the input based on the found strings and write the output
var outputFileAsListOfStrings = new List<string>();
foreach (var inputLineBeingProcessed in inputFileAsListOfStrings)
{
// is the input line one of the initialize statements identified previously?
// if so, rewrite the line.
// e.g.
// old line: StatusText = statusText;
// becomes: _statusText = statusText;
var isInitStmt = false;
foreach (var initStmt in initializeStatements)
{
if (inputLineBeingProcessed != initStmt) continue;
// we've found our statement; it is an initialize statement;
// now rewrite the format of the line as desired
var prefix = GetCodeLineIndentation(inputLineBeingProcessed);
var tabAndSpaceArray = new[] {' ', '\t'};
var inputLineWithoutPrefix = inputLineBeingProcessed.TrimStart(tabAndSpaceArray);
var outputLine = prefix + ConvertInitialCapitalToUnderscoreAndLowerCase(inputLineWithoutPrefix);
// write the line (preceded by its prefix) to the output file
outputFileAsListOfStrings.Add(outputLine);
Console.WriteLine("Rewrote INPUT: " + initStmt + " to OUTPUT: " + outputLine);
isInitStmt = true;
// we have now processed the input line; no need to loop through the initialize statements any further
break;
}
// if we've already determined the current input line is an initialize statement, no need to proceed further;
// go on to the next input line
if (isInitStmt)
continue;
// is the input line one of the "public virtual SomeType SomePropertyName" statements identified previously?
// if so, rewrite the single line as multiple lines of output.
// the input will look like this:
/*
public virtual SomeType SomePropertyName { get; set; }
*/
// first, we'll need a private variable which corresponds to the original statement in terms of name and type.
// what we'll do is, write the private field AFTER the public property, so as not to interfere with the XML
// comments above the "public virtual" statement.
// the output will be SIX LINES, as follows:
/*
public virtual SomeType SomePropertyName
{
get { return _somePropertyName; }
protected set { _someProperty = value; }
}
private SomeType _somePropertyName;
*/
var isPublicVirtualStatement = false;
foreach (var vp in virtualProps)
{
if (inputLineBeingProcessed != vp) continue;
// the input line being processed is a "public virtual" statement;
// convert it into the six line output format
var thisOutputList = new List<string>();
// first separate any indentation "prefix" that may exist (i.e. tabs and/or spaces),
// from the actual string of text representing the line of code
var prefix = GetCodeLineIndentation(inputLineBeingProcessed);
var tabAndSpaceArray = new[] { ' ', '\t' };
var inputLineWithoutPrefix = inputLineBeingProcessed.TrimStart(tabAndSpaceArray);
var originalVpStmt = inputLineWithoutPrefix.Split(' ');
// first output line (preceded by its original prefix)
var firstOutputLine = prefix +
originalVpStmt[0] + ' ' +
originalVpStmt[1] + ' ' +
originalVpStmt[2] + ' ' +
originalVpStmt[3];
thisOutputList.Add(firstOutputLine);
// second output line (indented to the same level as the original prefix)
thisOutputList.Add(prefix + "{");
// get field name from property name
var fieldName = ConvertInitialCapitalToUnderscoreAndLowerCase(originalVpStmt[3]);
// third output line (indented with the prefix, plus one more tab)
var thirdOutputLine = prefix + "\t" + "get { return " + fieldName + "; }";
thisOutputList.Add(thirdOutputLine);
// fourth output line (indented with the prefix, plus one more tab)
var fourthOutputLine = prefix + "\t" + "protected set { " + fieldName + " = value; }";
thisOutputList.Add(fourthOutputLine);
// fifth output line (indented to the same level as the first curly bracket)
thisOutputList.Add(prefix + "}");
// sixth output line (the "index 2" value of the original statement will be the string representing the .Net type)
// (indentation is the same as the "public virtual" statement above)
var sixthOutputLine = prefix +
"private" + ' ' +
originalVpStmt[2] + ' ' +
fieldName + ";";
thisOutputList.Add(sixthOutputLine);
// now write the six new lines to the master output list
outputFileAsListOfStrings.AddRange(thisOutputList);
isPublicVirtualStatement = true;
Console.WriteLine("Rewrote INPUT: " + inputLineBeingProcessed + " to OUTPUT: <multi-line block>");
break;
}
// if we've already determined the current input line is a "public virtual" statement, no need to proceed further;
// go on to the next input line
if (isPublicVirtualStatement)
continue;
// if we've gotten this far, the input statement is neither an "initialize" statement, nor a "public virtual" statement;
// So just write the output. Don't bother logging this as most lines will not be ones we'll process.
outputFileAsListOfStrings.Add(inputLineBeingProcessed);
}
// write the output file
var newPath = path.Replace(".cs", "-NEW.cs");
File.WriteAllLines(newPath, outputFileAsListOfStrings);
}
}

Is there an additional runtime cost for using named parameters?

Consider the following struct:
public struct vip
{
string email;
string name;
int category;
public vip(string email, int category, string name = "")
{
this.email = email;
this.name = name;
this.category = category;
}
}
Is there a performance difference between the following two calls?
var e = new vip(email: "foo", name: "bar", category: 32);
var e = new vip("foo", 32, "bar");
Is there a difference if there are no optional parameters defined?
I believe none. It's only a language/compiler feature, call it syntactic sugar if you like. The generated CLR code should be the same.
There's a compile-time cost, but not a runtime one...and the compile time is very, very minute.
Like extension methods or auto-implemented properties, this is just magic the compiler does, but in reality generates the same IL we're all familiar with and have been using for years.
Think about it this way, if you're using all the parameters, the compiler would call the method using all of them, if not, it would generate something like this behind the scenes:
var e = new vip(email: "foo", category: 32); //calling
//generated, this is what it's actually saving you from writing
public vip(string email, int category) : this(email, category, "bar") { }
No it is a compile-time feature only. If you inspect the generated IL you'll see no sign of the named parameters. Likewise, optional parameters is also a compile-time feature.
One thing to keep in mind regarding named parameters is that the names are now part of the signature for calling a method (if used obviously) at compile time. I.e. if names change the calling code must be changed as well if you recompile. A deployed assembly, on the other hand, will not be affected until recompiled, as the names are not present in the IL.
There shouldn't be any. Basically, named parameters and optional parameters are syntactic sugar; the compiler writes the actual values or the default values directly into the call site.
EDIT: Note that because they are a compiler feature, this means that changes to the parameters only get updated if you recompile the "clients". So if you change the default value of an optional parameter, for example, you will need to recompile all "clients", or else they will use the old default value.
Actually, there is cost at x64 CLR
Look at here http://www.dotnetperls.com/named-parameters
I am able to reproduce the result: named call takes 4.43 ns, and normal call takes 3.48 ns
(program runs in x64)
However, in x86, both take around 0.32 ns
The code is attached below, compile and run it yourself to see the difference.
Note that in VS2012 the default targat is AnyCPU x86 prefered, you have to switch to x64 to see the difference.
using System;
using System.Diagnostics;
class Program
{
const int _max = 100000000;
static void Main()
{
Method1();
Method2();
var s1 = Stopwatch.StartNew();
for (int i = 0; i < _max; i++)
{
Method1();
}
s1.Stop();
var s2 = Stopwatch.StartNew();
for (int i = 0; i < _max; i++)
{
Method2();
}
s2.Stop();
Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000 * 1000) /
_max).ToString("0.00 ns"));
Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000 * 1000) /
_max).ToString("0.00 ns"));
Console.Read();
}
static void Method1()
{
Method3(flag: true, size: 1, name: "Perl");
}
static void Method2()
{
Method3(1, "Perl", true);
}
static void Method3(int size, string name, bool flag)
{
if (!flag && size != -1 && name != null)
{
throw new Exception();
}
}
}

Resources