Skip Menu |

This queue is for tickets about the Unicode-Collate CPAN distribution.

Report information
The Basics
Id: 101170
Status: resolved
Priority: 0/
Queue: Unicode-Collate

People
Owner: Nobody in particular
Requestors: BULKDD [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: 1.09
Fixed in: (no value)



Subject: [PATCH] mass consting and some XS efficiency tweaks
Subject: 0001-mass-consting-and-some-XS-efficiency-tweaks.patch
From 4f1eec018889a5fe82e643c7e40515d0722d4888 Mon Sep 17 00:00:00 2001 From: bulk88 <bulk88@hotmail.com> Date: Sun, 28 Dec 2014 07:45:29 -0500 Subject: [PATCH] mass consting and some XS efficiency tweaks -remove "static const char *upperhex", this doesn't mean "0123456789ABCDEF" is static, but instead "char * upperhex" is static, and contains a pointer to "0123456789ABCDEF". Visual C doesn't optimize this extra variable away. -replace multiple XPUSHs with 1 EXTEND and PUSHs, less calls to Perl_stack_grow(), in some cases, the incoming arg proves there is space on perl stack, so no EXTEND needed then -replace MAX_DIV_16 with CPP constant so CC can optimizer better -add const to all the tables, this allows the tables to be shared between perl processes on most OSes (including Win32) by the OS image loader saving 100s of KB of malloc-style per perl process memory --- Collate.xs | 29 ++++++++++++++++------------- mkheader | 12 ++++++------ 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/Collate.xs b/Collate.xs index b0bc88c..e9ee74a 100644 --- a/Collate.xs +++ b/Collate.xs @@ -14,7 +14,7 @@ #define VALID_UTF_MAX (0x10ffff) #define OVER_UTF_MAX(uv) (VALID_UTF_MAX < (uv)) -static const UV max_div_16 = UV_MAX / 16; +#define MAX_DIV_16 (UV_MAX / 16) /* Supported Levels */ #define MinLevel (1) @@ -67,7 +67,7 @@ static const UV max_div_16 = UV_MAX / 16; #define CJK_CompIni (0xFA0E) #define CJK_CompFin (0xFA29) -static STDCHAR UnifiedCompat[] = { +static const STDCHAR UnifiedCompat[] = { 1,1,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,1,0,0,1,1,1 }; /* E F 0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 */ @@ -82,7 +82,7 @@ _fetch_rest () PREINIT: char ** rest; PPCODE: - for (rest = UCA_rest; *rest; ++rest) { + for (rest = (char **)UCA_rest; *rest; ++rest) { XPUSHs(sv_2mortal(newSVpv((char *) *rest, 0))); } @@ -105,12 +105,13 @@ _fetch_simple (uv) int i; int num = (int)*result; ++result; + EXTEND(SP, num); for (i = 0; i < num; ++i) { - XPUSHs(sv_2mortal(newSVpvn((char *) result, VCE_Length))); + PUSHs(sv_2mortal(newSVpvn((char *) result, VCE_Length))); result += VCE_Length; } } else { - XPUSHs(sv_2mortal(newSViv(0))); + PUSHs(sv_2mortal(newSViv(0))); } SV* @@ -163,7 +164,7 @@ _getHexArray (src) break; if (overflowed) continue; - if (value > max_div_16) { + if (value > MAX_DIV_16) { overflowed = TRUE; continue; } @@ -205,10 +206,11 @@ _decompHangul (code) vindex = (sindex % Hangul_NCount) / Hangul_TCount; tindex = sindex % Hangul_TCount; - XPUSHs(sv_2mortal(newSVuv(lindex + Hangul_LBase))); - XPUSHs(sv_2mortal(newSVuv(vindex + Hangul_VBase))); + EXTEND(SP, 3); + PUSHs(sv_2mortal(newSVuv(lindex + Hangul_LBase))); + PUSHs(sv_2mortal(newSVuv(vindex + Hangul_VBase))); if (tindex) - XPUSHs(sv_2mortal(newSVuv(tindex + Hangul_TBase))); + PUSHs(sv_2mortal(newSVuv(tindex + Hangul_TBase))); SV* @@ -319,8 +321,9 @@ _derivCE_8 (code) b[2] = (U8)(bbbb & 0xFF); a[7] = b[7] = (U8)(code >> 8); a[8] = b[8] = (U8)(code & 0xFF); - XPUSHs(sv_2mortal(newSVpvn((char *) a, VCE_Length))); - XPUSHs(sv_2mortal(newSVpvn((char *) b, VCE_Length))); + EXTEND(SP, 2); + PUSHs(sv_2mortal(newSVpvn((char *) a, VCE_Length))); + PUSHs(sv_2mortal(newSVpvn((char *) b, VCE_Length))); void @@ -331,7 +334,7 @@ _uideoCE_8 (code) PPCODE: uice[1] = uice[7] = (U8)(code >> 8); uice[2] = uice[8] = (U8)(code & 0xFF); - XPUSHs(sv_2mortal(newSVpvn((char *) uice, VCE_Length))); + PUSHs(sv_2mortal(newSVpvn((char *) uice, VCE_Length))); SV* @@ -598,7 +601,7 @@ visualizeSortKey (self, key) STRLEN klen, dlen; UV uv; IV uca_vers, sep = 0; - static const char *upperhex = "0123456789ABCDEF"; + const char *upperhex = "0123456789ABCDEF"; CODE: if (SvROK(self) && SvTYPE(SvRV(self)) == SVt_PVHV) selfHV = (HV*)SvRV(self); diff --git a/mkheader b/mkheader index a575f43..7e2aebe 100644 --- a/mkheader +++ b/mkheader @@ -105,10 +105,10 @@ sub stringify { my $init = ''; { - my $type = "char*"; + my $type = "char* const"; my $head = $prefix."rest"; - $init .= "static $type $head [] = {\n"; + $init .= "static const $type $head [] = {\n"; for my $line (@Rest) { $line =~ s/\s*\z//; next if $line eq ''; @@ -123,7 +123,7 @@ my @tripletable = ( { file => "ucatbl", name => "simple", - type => "char*", + type => "char* const", hash => \%SimpleEntries, null => "NULL", init => $init, @@ -162,7 +162,7 @@ EOF next if ! $val{ $p }; for (my $r = 0; $r < 256; $r++) { next if ! $val{ $p }{ $r }; - printf "static $type ${head}_%02x_%02x [256] = {\n", $p, $r; + printf "static const $type ${head}_%02x_%02x [256] = {\n", $p, $r; for (my $c = 0; $c < 256; $c++) { print "\t", defined $val{$p}{$r}{$c} ? "($type)".$val{$p}{$r}{$c} @@ -175,7 +175,7 @@ EOF } foreach my $p (sort { $a <=> $b } keys %val) { next if ! $val{ $p }; - printf "static $type* ${head}_%02x [256] = {\n", $p; + printf "static const $type* const ${head}_%02x [256] = {\n", $p; for (my $r = 0; $r < 256; $r++) { print $val{ $p }{ $r } ? sprintf("${head}_%02x_%02x", $p, $r) @@ -185,7 +185,7 @@ EOF } print "};\n\n"; } - print "static $type** $head [] = {\n"; + print "static const $type* const * const $head [] = {\n"; for (my $p = 0; $p <= 0x10; $p++) { print $val{ $p } ? sprintf("${head}_%02x", $p) : "NULL"; print ',' if $p != 0x10; -- 1.8.0.msysgit.0
On Sun Dec 28 08:50:13 2014, BULKDD wrote: Show quoted text
> This transaction appears to have no content
Previous U::C had about half its tables in read-write memory. Although Win32 (and probably linux) were smart enough to figure out "read write" memory can be shared between perl processes and the disk image until it is first written to, let us not rely on this feature and properly const the data. Also, since "copy-on-write" can become deshared at any random point, all COW data (284KB in before pic) was already charged against my ulimit (assuming I turned on per user account memory limit in Windows, and almost nobody does that), as noted by the "private" column. Shareable and shared are the same for purpose of comparison. I forgot to start a 2nd perl process to make the picture so shared column is empty. 832KB highlighted entry with address of 0x180000000 is Collate.dll on Win64.
Subject: collateafter.PNG
Download collateafter.PNG
image/png 41.8k
collateafter.PNG
Subject: collatebefore.png
Download collatebefore.png
image/png 42.9k
collatebefore.png
Subject: Re: [rt.cpan.org #101170] [PATCH] mass consting and some XS efficiency tweaks
Date: Sun, 04 Jan 2015 16:38:44 +0900
To: bug-Unicode-Collate [...] rt.cpan.org
From: Sadahiro Tomoyuki <rsn10260 [...] nifty.com>
Thank you for your report and patch !! Sadahiro Tomoyuki "Daniel Dragan via RT" <bug-Unicode-Collate@rt.cpan.org> wrote: Show quoted text
> Queue: Unicode-Collate > Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=101170 > > > On Sun Dec 28 08:50:13 2014, BULKDD wrote:
> > This transaction appears to have no content
> > Previous U::C had about half its tables in read-write memory. Although Win32 (and probably linux) were smart enough to figure out "read write" memory can be shared between perl processes and the disk image until it is first written to, let us not rely on this feature and properly const the data. Also, since "copy-on-write" can become deshared at any random point, all COW data (284KB in before pic) was already charged against my ulimit (assuming I turned on per user account memory limit in Windows, and almost nobody does that), as noted by the "private" column. Shareable and shared are the same for purpose of comparison. I forgot to start a 2nd perl process to make the picture so shared column is empty. 832KB highlighted entry with address of 0x180000000 is Collate.dll on Win64.