[Mono-devel-list] Catastrophical performance for simple unsafe code

Paolo Molaro lupus at ximian.com
Thu May 6 05:04:56 EDT 2004

On 05/05/04 Andreas Nahr wrote:
> as some may know I'm currently optimizing the String class. However I'm
> stuck at this point:
> Check out the attached benchmark. On my system (x86 Windows) I get the
> following results:
> Copy using ints: 1302ms
> Copy using long: 721ms
> Obviously these results are absolute nonsense.
> The copy using ints should be at least equally fast as the copy using long
> (in fact it should be a little bit faster).
> Feel free to try on .Net and you will find out that .Net delivers exactly
> the result you would assume that this benchmark delivers (int being slightly
> faster than long).

FWIW, on my MS .net 1.0, the int results are about 10% slower than the
long one.

> Also the overall speed for this is VERY slow. Compare it to the MS impl.

Yes, the most obvious reason was that unsafe pointers were not
considered in the global register allocator. This alone cuts the runtime
in half. The attached patch also adds a couple other tweaks for an
overall 2.5 speedup on my machine. Care to test?
If anyone has both the 1.0 and 1.1 MS runtime on the same machine, I
would appreciate the results of the benchmark on both, to see if there
is any significant difference (you probably want to mail them to me
off-list, since the eula probably forbids to share those numbers in
This should let you have better figures for your string enhancements,
compared to the current icalls.
Unsafe code is not widely used, so I guess nobody looked at the
performance issues with it. Thanks for the report, though there is no
need to panic: there are likely several places in mono where similar 2+
times speedups could be achieved with simple one-liner patches. we just
need people to report and a few minutes of time to look at the issues
(though I won't claim all the eprformance issues could be addressed as
easily as this, which could probably use some improvement, too).


lupus at debian.org                                     debian/rules
lupus at ximian.com                             Monkeys do it better
-------------- next part --------------
Index: cfold.c
RCS file: /cvs/public/mono/mono/mini/cfold.c,v
retrieving revision 1.2
diff -u -p -r1.2 cfold.c
--- cfold.c	6 Jun 2003 13:05:31 -0000	1.2
+++ cfold.c	6 May 2004 07:57:39 -0000
@@ -195,7 +195,16 @@ mono_constant_fold_inst (MonoInst *inst,
 			inst->opcode = OP_I8CONST;
 			inst->inst_l = inst->inst_i0->inst_c0;
-	return;
+		return;
+	case CEE_CONV_I:
+	case CEE_CONV_U:
+		if (inst->inst_i0->opcode == OP_ICONST) {
+			inst->opcode = OP_ICONST;
+			inst->inst_l = inst->inst_i0->inst_c0;
+		} else if (inst->inst_i0->opcode == CEE_LDIND_I) {
+			*inst = *inst->inst_i0;
+		}
+		return;
 	/* we should be able to handle isinst and castclass as well */
 	case CEE_ISINST:
Index: inssel-x86.brg
RCS file: /cvs/public/mono/mono/mini/inssel-x86.brg,v
retrieving revision 1.19
diff -u -p -r1.19 inssel-x86.brg
--- inssel-x86.brg	13 Apr 2004 20:15:05 -0000	1.19
+++ inssel-x86.brg	6 May 2004 07:57:41 -0000
@@ -491,6 +491,7 @@ stmt: CEE_STIND_I4 (OP_REGVAR, CEE_SUB (
 	mono_bblock_add_inst (s->cbb, tree);
 	int con = state->right->right->tree->inst_c0;
 	int dreg = state->left->tree->dreg;
Index: mini-x86.c
RCS file: /cvs/public/mono/mono/mini/mini-x86.c,v
retrieving revision 1.88
diff -u -p -r1.88 mini-x86.c
--- mini-x86.c	28 Apr 2004 12:49:44 -0000	1.88
+++ mini-x86.c	6 May 2004 07:57:41 -0000
@@ -217,6 +217,7 @@ is_regsize_var (MonoType *t) {
 	case MONO_TYPE_U4:
 	case MONO_TYPE_I:
 	case MONO_TYPE_U:
 		return TRUE;

More information about the Mono-devel-list mailing list