Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Scaevolus
Apr 16, 2007

N.Z.'s Champion posted:

This is probably a stupid question but lets say that I've got variables A and B... is there a way to swap their values without using a third variable (Eg, C = A, A = B, B = C) and without meddling with pointers?

I guess I was just wondering whether there's some syntax for this that I was unaware of, perhaps in a single expression.

(in Python, PHP, whatever)

Do you guys go to the same school?

Adbot
ADBOT LOVES YOU

N.Z.'s Champion
Jun 8, 2003

Yam Slacker

Scaevolus posted:

Do you guys go to the same school?

Heh, I was just looking at a min/max check where the user was giving the values in the wrong order and so I wanted to swap them if A > B. It's a coincidence and I wasn't following this thread. Sorry everyone for the derail. I'm a loving idiot.

N.Z.'s Champion fucked around with this message at 23:28 on Aug 25, 2008

POKEMAN SAM
Jul 8, 2004
Also, why is everyone afraid of these mysterious "temporary variables"?

N.Z.'s Champion
Jun 8, 2003

Yam Slacker

Ugg boots posted:

Also, why is everyone afraid of these mysterious "temporary variables"?

I guess it just sounds like an easy optimisation that could result in shorter/clearer code. Is it not?

Incoherence
May 22, 2004

POYO AND TEAR

N.Z.'s Champion posted:

I guess it just sounds like an easy optimisation that could result in shorter/clearer code. Is it not?
Could it gain you some memory? Possibly, but it might not be worth worrying about unless you're doing a lot of these swaps.

Could it make your code shorter? Possibly, but this is sometimes in conflict with making it clearer.

Could it make your code clearer? Many optimizations don't, and since you don't know how this would be done, it's difficult for you to say.

The XOR trick probably works in more languages than tuple-unpacking in Python, but it has a significant effect on code clarity (what the gently caress are all of these ^=s doing in my code), and as an optimization it's fairly negligible.

Scaevolus
Apr 16, 2007

Using a few extra bytes for a temporary variable is almost certainly going to be both clearer and faster than a "clever" xor trick.

N.Z.'s Champion
Jun 8, 2003

Yam Slacker
I'm not a clever illegible hacks kind of programmer, and I'm already well convinced about the value of readable code.

The Python unpacking technique seems to be better in almost all ways though. That's the kind of thing I was after, thanks :)

N.Z.'s Champion fucked around with this message at 00:49 on Aug 26, 2008

zootm
Aug 8, 2006

We used to be better friends.

N.Z.'s Champion posted:

So unpacking tuples works in Python, but can this be done in PHP?
Apparently this works:
code:
list($a,$b) = array($b,$a);
This is probably just as inefficient as it looks, though. Just use the drat temporary variable, it's the only good excuse to use the variable name temp and you should revel in that.

His Divine Shadow
Aug 7, 2000

I'm not a fascist. I'm a priest. Fascists dress up in black and tell people what to do.
Stupid question, I am using ASP and SQL to make a recursive subroutine, at the end it calls itself like this SubroutineName(Value), it works and the code iterates as long as is needed, but I'd like to carry more info over the next iteration than just the value of the parentID, I'd also like it's parents parentID, like eh, grandparentID.

How do I add more values because just doing SubroutineName(Value1,Value2) doesn't work but says "Cannot use parentheses when calling a Sub", so yeah I'm not sure how to proceed here, I've learned coding this stuff via trial & error mostly so I bet am missing some simple piece of info here on how to properly work with values in subroutines.

EDIT: stupidly easy answer: SubRoutineName(value1),(value2)

His Divine Shadow fucked around with this message at 14:04 on Aug 26, 2008

Janitor Prime
Jan 22, 2004

PC LOAD LETTER

What da fuck does that mean

Fun Shoe

Incoherence posted:

The XOR trick probably works in more languages than tuple-unpacking in Python, but it has a significant effect on code clarity (what the gently caress are all of these ^=s doing in my code), and as an optimization it's fairly negligible.

If everyone knows about the trick then how does that make it unreadable. I think a comment like this would do just fine.
code:
// Swapping variables using stupid XOR trick
x ^= y;
y ^= x;
x ^= y;

more falafel please
Feb 26, 2005

forums poster

Incoherence posted:

The XOR trick probably works in more languages than tuple-unpacking in Python, but it has a significant effect on code clarity (what the gently caress are all of these ^=s doing in my code), and as an optimization it's fairly negligible.

The XOR trick is not an optimization, it's a trick. On modern CPUs it's actually slower because of pipelining. It's a "clever" trick undergrads show off to their friends.

swap_xor.c:
code:
void swap(int* a, int* b)
{
    *a ^= *b;
    *b ^= *a;
    *a ^= *b;
}

int main(int argc, char** argv)
{
    if (argc < 2) return 0;
    int n = atoi(argv[1]);
    int a = 42;
    int b = 6*9;

    int i;
    for (i = 0; i < n; ++i)
    {
        swap(&a, &b);
    }

    return 0;
}
swap_assign.c:
code:
void swap(int* a, int* b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main(int argc, char** argv)
{
    if (argc < 2) return 0;
    int n = atoi(argv[1]);
    int a = 42;
    int b = 6*9;

    int i;
    for (i = 0; i < n; ++i)
    {
        swap(&a, &b);
    }

    return 0;
}
code:
$ time ./swap_xor 1000000

real	0m0.013s
user	0m0.011s
sys	0m0.002s
$ time ./swap_assign 1000000

real	0m0.009s
user	0m0.008s
sys	0m0.002s
$ time ./swap_xor 10000000

real	0m0.104s
user	0m0.102s
sys	0m0.002s
$ time ./swap_assign 10000000

real	0m0.077s
user	0m0.074s
sys	0m0.002s
$ time ./swap_xor 100000000

real	0m1.022s
user	0m1.018s
sys	0m0.004s
$ time ./swap_assign 100000000

real	0m0.737s
user	0m0.732s
sys	0m0.003s
$ time ./swap_xor 1000000000

real	0m10.210s
user	0m10.178s
sys	0m0.030s
$ time ./swap_assign 1000000000

real	0m7.331s
user	0m7.310s
sys	0m0.014s
Unless you're optimizing for cleverness, or on a CPU with little to no instruction pipeline, don't ever do this.

tef
May 30, 2004

-> some l-system crap ->

more falafel please posted:

The XOR trick is not an optimization, it's a trick.
Unless you're optimizing for cleverness, or on a CPU with little to no instruction pipeline, don't ever do this.

I did this to annoy my tutor in CS1. He retaliated by making me explain it to the rest of the group.

The group who were told to chant "public static void main" as he had abandoned all hope of getting them to be able more than one question.

Scaevolus
Apr 16, 2007

tef posted:

He retaliated by making me explain it to the rest of the group.
How long did it take for them to understand the binary representation of integers?

tef
May 30, 2004

-> some l-system crap ->

Scaevolus posted:

How long did it take for them to understand the binary representation of integers?

A while, or at least they were good at nodding. Suprisingly enough from first principles most of them were able to follow the explanation -- although I doubt much of it made it's way into their memory.

On the other hand, chanting "public static void main" is going to stay with me for a while.

JawnV6
Jul 4, 2004

So hot ...

more falafel please posted:

The XOR trick is not an optimization, it's a trick. On modern CPUs it's actually slower because of pipelining. It's a "clever" trick undergrads show off to their friends.

Inline the function and don't use pointers. See if there's still a difference.

On the functions you wrote, xor is doing 3 loads and 3 stores, assign is doing 2 loads, 2 stores, and using an extra register. The difference in speed is because of the loads/stores, not 'pipelining'. mov and xor will get through exactly the same.

floWenoL
Oct 23, 2002

JawnV6 posted:

Inline the function and don't use pointers. See if there's still a difference.

On the functions you wrote, xor is doing 3 loads and 3 stores, assign is doing 2 loads, 2 stores, and using an extra register. The difference in speed is because of the loads/stores, not 'pipelining'. mov and xor will get through exactly the same.

Making the swap function static will probably cause it to be inlined, if it's not already.

Edit:
It's probably best to show the optimized generated assembly, instead of speculating as to what the compiler did.

floWenoL fucked around with this message at 21:42 on Aug 26, 2008

Scaevolus
Apr 16, 2007

edit: so apparently it completely optimized out the variables it was swapping, because they never did anything :downs:

Scaevolus fucked around with this message at 22:18 on Aug 26, 2008

JawnV6
Jul 4, 2004

So hot ...

Scaevolus posted:

-O3 yields the same assembly, and -O uses "movl $0, %eax" instead of "xorl %eax, %eax".
Ugh what a stupid unreadable hack to zero out a register. I despise this 'xor trick'

more falafel please
Feb 26, 2005

forums poster

inlined, no pointers:
code:
1000 iterations:

real    0m0.002s
user    0m0.000s
sys     0m0.001s

real    0m0.002s
user    0m0.000s
sys     0m0.001s

1000000 iterations:

real    0m0.010s
user    0m0.008s
sys     0m0.001s

real    0m0.006s
user    0m0.005s
sys     0m0.001s

10000000 iterations:

real    0m0.083s
user    0m0.081s
sys     0m0.002s

real    0m0.044s
user    0m0.043s
sys     0m0.002s

100000000 iterations:

real    0m0.813s
user    0m0.810s
sys     0m0.003s

real    0m0.426s
user    0m0.424s
sys     0m0.003s

1000000000 iterations:

real    0m8.112s
user    0m8.092s
sys     0m0.019s

real    0m4.248s
user    0m4.237s
sys     0m0.010s
Unoptimized assembly, swap_assign.s (the important part, I took out all the argument code and atoi/dylib stub code):
code:
    jmp L5
L6:
    movl    -24(%ebp), %eax
    movl    %eax, -12(%ebp)
    movl    -20(%ebp), %eax
    movl    %eax, -24(%ebp)
    movl    -12(%ebp), %eax
    movl    %eax, -20(%ebp)
    leal    -16(%ebp), %eax
    incl    (%eax)
L5:
    movl    -16(%ebp), %eax
    cmpl    -28(%ebp), %eax
    jl  L6
    movl    $0, -44(%ebp)
L4:
    movl    -44(%ebp), %eax
    leave
    ret
Unoptimized assembly, swap_xor.s:
code:
L6:
    movl    -16(%ebp), %edx
    leal    -20(%ebp), %eax
    xorl    %edx, (%eax)
    movl    -20(%ebp), %edx
    leal    -16(%ebp), %eax
    xorl    %edx, (%eax)
    movl    -16(%ebp), %edx
    leal    -20(%ebp), %eax
    xorl    %edx, (%eax)
    leal    -12(%ebp), %eax
    incl    (%eax)
L5:
    movl    -12(%ebp), %eax
    cmpl    -24(%ebp), %eax
    jl  L6
    movl    $0, -28(%ebp)
L4:
    movl    -28(%ebp), %eax
    leave
    ret
Turning on even -O1 causes the swaps to get compiled out since the variables are never used outside of there.

edit: partially beaten, mine has the unoptimized assembly

Scaevolus
Apr 16, 2007

more falafel please posted:

edit: partially beaten, mine has the unoptimized assembly
s/partially/completely/; no one cares about unoptimized assembly, the whole point is for it to be savage :colbert:

edit: gently caress

Scaevolus fucked around with this message at 22:18 on Aug 26, 2008

more falafel please
Feb 26, 2005

forums poster

JawnV6 posted:

Ugh what a stupid unreadable hack to zero out a register. I despise this 'xor trick'

I used to use xor a on the Z80 because it was only 1 byte and like 2 cycles whereas the immediate move was 2 bytes and like 5 cycles or something.

But to be fair that was the Z80.

more falafel please
Feb 26, 2005

forums poster

Scaevolus posted:

s/partially/completely/; no one cares about unoptimized assembly, the whole point is for it to be savage :colbert:

:smith:

more falafel please
Feb 26, 2005

forums poster

Scaevolus posted:

s/partially/completely/; no one cares about unoptimized assembly, the whole point is for it to be savage :colbert:

It's only 'savage' because it optimized out the swaps altogether :pwn;

Triple post woo

JawnV6
Jul 4, 2004

So hot ...

more falafel please posted:

I used to use xor a on the Z80 because it was only 1 byte and like 2 cycles whereas the immediate move was 2 bytes and like 5 cycles or something.

But to be fair that was the Z80.

On EMT64 (lol) using the 64 bit xor takes an extra byte, the 32 bit xor will zero the upper half of the register anyway :v:

floWenoL
Oct 23, 2002

Okay, this is how you do the benchmark. First you post the code, making sure to put something in to prevent the compiler from optimizing the whole thing out:

code:
/* xorswap.c */
#include <stdio.h>
#include <stdlib.h>

static inline void swap(int *a, int *b) {
  *a ^= *b;
  *b ^= *a;
  *a ^= *b;
}

int main(int argc, char **argv) {
  int n, a, b;
  if (argc < 4) return 0;
  n = atoi(argv[1]);
  a = atoi(argv[2]);
  b = atoi(argv[3]);
  while (--n >= 0) swap(&a, &b);
  printf("%d %d\n", a, b);
  return 0;
}
code:
/* tmpswap.c */
#include <stdio.h>
#include <stdlib.h>

static inline void swap(int *a, int *b) {
  int tmp = *a;
  *a = *b;
  *b = tmp;
}

int main(int argc, char **argv) {
  int n, a, b;
  if (argc < 4) return 0;
  n = atoi(argv[1]);
  a = atoi(argv[2]);
  b = atoi(argv[3]);
  while (--n >= 0) swap(&a, &b);
  printf("%d %d\n", a, b);
  return 0;
}
Then you post your compiler version/commands, making sure to actually turn optimizations on fully:

code:
$ gcc --version
gcc (GCC) 4.0.3 (Ubuntu 4.0.3-1ubuntu5)
$ gcc -O3 -Wall tmpswap.c -S
$ gcc -O3 -Wall xorswap.c -S
$ gcc -O3 -Wall tmpswap.c -o tmpswap
$ gcc -O3 -Wall xorswap.c -o xorswap
Then you post the relevant parts of the generated assembly:

code:
# tmpswap.s
.L14:
	movl	%eax, %ecx
	movl	%edx, %eax
.L7: # entry point
	addl	$1, %ebx
	movl	%ecx, %edx
	cmpl	%esi, %ebx
	jne	.L14
code:
# xorswap.s
.L7: # entry point
	xchgl	%eax, %ecx
	addl	$1, %edx
	cmpl	%edx, %ebx
	jne	.L7
Then you post your results and analysis:

code:
$ time ./tmpswap 2000000000 3 5
3 5

real    0m1.993s
user    0m1.965s
sys     0m0.006s
$ time ./xorswap 2000000000 3 5
3 5

real    0m2.042s
user    0m1.980s
sys     0m0.002s
It's a wash, and I get different results when I run it multiple times. It also might be worth doing the benchmark in assembly, i.e. comparing xchgl with tmp with xor.

floWenoL fucked around with this message at 00:02 on Aug 27, 2008

more falafel please
Feb 26, 2005

forums poster

floWenoL posted:

Okay, this is how you do the benchmark. First you post the code, making sure to put something in to prevent the compiler from optimizing the whole thing out:


Then you post the relevant parts of the generated assembly:

code:
# tmpswap.s
.L14:
	movl	%eax, %ecx
	movl	%edx, %eax
.L7: # entry point
	addl	$1, %ebx
	movl	%ecx, %edx
	cmpl	%esi, %ebx
	jne	.L14
code:
# xorswap.s
.L7: # entry point
	xchgl	%eax, %ecx
	addl	$1, %edx
	cmpl	%edx, %ebx
	jne	.L7

Ok, but I think my point still stands, the compiler optimizes out the xor trick because it's not actually an optimization.

floWenoL
Oct 23, 2002

more falafel please posted:

Ok, but I think my point still stands, the compiler optimizes out the xor trick because it's not actually an optimization.

Yeah, it's inconclusive. I'd test the xor trick in assembly but :effort:. Also, I wonder if gcc actually detects the xor trick or if it just falls out of the data flow analysis.

minidracula
Dec 22, 2007

boo woo boo
More simple .NET-related questions:

Edit: moving these to the .NET thread, if they're not already answered there.

minidracula fucked around with this message at 02:24 on Aug 27, 2008

csammis
Aug 26, 2003

Mental Institution

mnd posted:

More simple .NET-related questions:

We have a megathread for .NET, please use it

Arconom
Jun 27, 2006
Edouard Joseph Gilliath 1417 - 1460 Battle of Arkinholm risen again to protect
Anyone here done any procedurally generated maps and the like? I want to write some code to procedurally generate a world from the depths of the ocean upward, and I'm looking for a mysterious code ninja to point me in the right direction. I have never done any procedurally generated coding.

Scaevolus
Apr 16, 2007

Arconom posted:

Anyone here done any procedurally generated maps and the like? I want to write some code to procedurally generate a world from the depths of the ocean upward, and I'm looking for a mysterious code ninja to point me in the right direction. I have never done any procedurally generated coding.
Look at how Terragen does things, and maybe read these articles. You'll probably end up using Perlin noise a lot.

chglcu
May 17, 2007

I'm so bored with the USA.

Arconom posted:

Anyone here done any procedurally generated maps and the like? I want to write some code to procedurally generate a world from the depths of the ocean upward, and I'm looking for a mysterious code ninja to point me in the right direction. I have never done any procedurally generated coding.

This book is pretty awesome: Texturing & Modeling: A Procedural Approach. A lot of the stuff in it isn't necessarily intended for real-time rendering but can be adapted for it, or be used to generate static resources to distribute with your app.

Arconom
Jun 27, 2006
Edouard Joseph Gilliath 1417 - 1460 Battle of Arkinholm risen again to protect
Those articles on world building are exactly what I'm looking for. Now I have to learn how to somehow integrate the procedural generation with genetic algorithms to produce ideal results. Ugh. What a tedious hobby.

nonathlon
Jul 9, 2004
And yet, somehow, now it's my fault ...
I'm casting about looking for a suitable cross-platform installer. That is, I have some commandline programs to distribute, that have to be installed by non-technical types, and I'd rather work with a single installer type / product, even if I'll have to produce different installers for each platform.

Of course, the best examples are commercial and expensive (InstallAnywhere, InstallBuilder etc.) or don't support Macs. izPack looked good, but doesn't seem to have any support for installs that require permissions. That is, if the user wants to install into /usr/local/bin, izPack just complains it can't write to that directory, rather than asking for credentials. (The release refers to a feature called "SudoPanel", but it's completely undocumented.)

I've also looked as vainstall, Openjinstaller, jexpress, Advanced installer, Install4J, INstallJammer, Liftoff, Mini, and Innosetup. (Undocumented and buggy, no Mac version & still in dev, commercial, Windows based, Mac support "coming" ...)

Any other suggestions, or an I fresh out of luck?

tef
May 30, 2004

-> some l-system crap ->

outlier posted:

I'm casting about looking for a suitable cross-platform installer

Mac applications tend to come stand alone - you drag Application.app into /Applications

Installers aren't very popular.

nonathlon
Jul 9, 2004
And yet, somehow, now it's my fault ...

tef posted:

Mac applications tend to come stand alone - you drag Application.app into /Applications

Installers aren't very popular.

outlier posted:

I have some commandline programs to distribute, that have to be installed by non-technical types

An installer is needed. I can't ask people to drag a binary into /usr/local/bin.

tef
May 30, 2004

-> some l-system crap ->
On a complete aside:

If you are curious about joel atwood and jeff spolsky's latest adventure 'stackoverflow', but not enough of a rockstar to get in the beta, fear not:

Go to:

http://beta.stackoverflow.com

Change your cookies - type this into the address bar:

javascript:alert(document.cookie="soba=-9999999");

(any big negative number seems to work)

And then go back to:

http://beta.stackoverflow.com and refresh!

Volia!

tef fucked around with this message at 17:57 on Aug 29, 2008

POKEMAN SAM
Jul 8, 2004

tef posted:

On a complete aside:

If you are curious about joel atwood and jeff spolsky's latest adventure 'stackoverflow', but not enough of a rockstar to get in the beta, fear not:

Go to:

http://beta.stackoveflow.com

Change your cookies - type this into the address bar:

javascript:alert(document.cookie="soba=-9999999");

(any big negative number seems to work)

And then go back to:

http://beta.stackoveflow.com and refresh!

Volia!

Hahahahahahaahahahahahahahahahahahaha

I don't know what else to say (other than you typoed the links.)

Stephen
Feb 6, 2004

Stoned
Hah oh god that worked like a charm. I read Jeff Atwood's blog all the time, but I'm starting to think he's not as good as I first thought!

Adbot
ADBOT LOVES YOU

POKEMAN SAM
Jul 8, 2004

Stephen posted:

Hah oh god that worked like a charm. I read Jeff Atwood's blog all the time, but I'm starting to think he's not as good as I first thought!

Ugh, now I started posting on StackOverflow. It's not bad, but they're going to want to make a better "front page" because just listing off a bunch of seemingly random questions is kind of a clusterfuck.

I like the achievement style badges :D


Edit: What the gently caress does reputation represent? Is there some sort of formula based on badges and tags and stuff?

Edit 2: Found the formula.

POKEMAN SAM fucked around with this message at 19:21 on Aug 29, 2008

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply