{"id":18526714,"url":"https://github.com/rogusdev/countbits","last_synced_at":"2025-06-21T08:34:27.939Z","repository":{"id":4531806,"uuid":"5672031","full_name":"rogusdev/countbits","owner":"rogusdev","description":"exploring the speed of varying languages at counting bits","archived":false,"fork":false,"pushed_at":"2022-12-07T18:28:03.000Z","size":61,"stargazers_count":1,"open_issues_count":3,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-16T10:08:54.256Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rogusdev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-09-04T12:23:33.000Z","updated_at":"2020-10-18T22:36:28.000Z","dependencies_parsed_at":"2023-01-11T16:36:07.257Z","dependency_job_id":null,"html_url":"https://github.com/rogusdev/countbits","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rogusdev/countbits","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rogusdev%2Fcountbits","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rogusdev%2Fcountbits/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rogusdev%2Fcountbits/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rogusdev%2Fcountbits/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rogusdev","download_url":"https://codeload.github.com/rogusdev/countbits/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rogusdev%2Fcountbits/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261093227,"owners_count":23108622,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-06T17:52:17.027Z","updated_at":"2025-06-21T08:34:22.918Z","avatar_url":"https://github.com/rogusdev.png","language":"Shell","readme":"# countbits\n\nexploring the speed of varying languages at counting \"on\" bits in integers, and other fun comparisons\n\nRuns ec2 instances for each benchmark test and outputs results to s3\n\nThis is based on an interview question I encountered where the interviewer asked me\nhow I would count \"on\" bits in an integer, given repeated unpredictable requests (i.e. a service)\nand I suggested a lookup table, and he *scoffed* that this would be even remotely feasible.\nTold me that even if it could fit (uhh, 32 bits is 4 gb?) it would take too long to generate.\n(He wanted me to propose a caching scheme.  I did not pursue the job.)\n\nSo, let's see how long it does take to generate ;)\n\n## Stats\n\nCountbits, average per 10mm:\n- Go 1.15.2 ~0.5s\n- C ~1.0s\n- C# dotnet core 3.1.402 ~1.7s\n- Javascript / Node 14 (Naive write) OOM ~5.4s\n- Javascript / Node 14 (Readable -\u003e pipe) ~7.7s\n- Java 11 (AdoptOpenJDK 11.0.8+10) (Classes) ~18s\n- Java 11 (AdoptOpenJDK 11.0.8+10) (Optimized primitives) ~18s\n- JRuby 9.2.13.0 ~23s\n- PHP 7.4.3 ~27s\n- Ruby 2.7.1 ~28s\n- Python 3.8.2 ~101s\n- Rust 1.46.0 ~?s (needs entire implementation)\n\nFibonacci 42:\n- C ~1.2s\n- Rust 1.46.0 ~1.7s\n- Java 11 (AdoptOpenJDK 11.0.8+10) ~1.8s\n- C# dotnet core 3.1.402 ~2.7s\n- Javascript / Node 14 ~4.5s\n- Go 1.15.2 ~4.9s\n- JRuby 9.2.13.0 ~22s\n- PHP 7.4.3 ~23s\n- Ruby 2.7.1 ~36s\n- Python 3.8.2 ~109s\n\nSignificant changes relative to the past test:\n- Go got much slower on both countbits and fibonacci -- until some improvements came in for countbits to speed it up a lot!\n- (the go improvements make me wonder how much other languages could be trivially optimized as well)\n- Python got faster (slightly) -- but still a half dead slug\n- C# got 5x faster on fibonacci (previous result was very different vs other langues compared to countbits relative perf)\n\n## Running\n\n_After one time setup of your ec2 account as per instructions at the bottom (role, policy, bucket, security group, keypair, etc)_\n\nFirst set your `PROFILE` and `BUCKET` in `run.sh` and `clean.sh` ala:\n\n    AWS_PROFILE=yourAWSprofile\n    AWS_BUCKET=yourAWSs3bucket\n    sed -i \"s|PROFILE=...|PROFILE=$AWS_PROFILE|\" run.sh\n    sed -i \"s|BUCKET=...|BUCKET=$AWS_BUCKET|\" run.sh\n    sed -i \"s|PROFILE=...|PROFILE=$AWS_PROFILE|\" clean.sh\n    sed -i \"s|BUCKET=...|BUCKET=$AWS_BUCKET|\" clean.sh\n\nRun the perf benchmarks with `. run.sh countbits` or `. run.sh fibonacci 42` (you can run more than one at a time).\n\nThen download the results with `. clean.sh` (which also removes the results from your s3 bucket -- note that it does not stop running ec2 instances)\n\n## Debugging\n\nSome debugging and lookup tools you might want afterwards:\n```\n# http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AccessingInstancesLinux.html\nssh -i ~/.ssh/$KEYPAIR.pem ubuntu@$DOMAIN\n\ntail -f /var/log/cloud-init-output.log\n\nsudo su\ncat /root/countbits/fibonacci/csharp/fibonacci_*_out.txt\n\n\naws s3 ls --profile $PROFILE $BUCKET/$TYPE/\naws s3 cp --profile $PROFILE s3://$BUCKET/$TYPE/output_DATETIME.json ./\n\n# https://stedolan.github.io/jq/tutorial/\nsudo apt-get install jq\ncat output_DATETIME.json | jq\n\n\naws ec2 describe-instances --profile $PROFILE --region $REGION --query 'Reservations[*].Instances[*].[LaunchTime, InstanceId, State.Name, Tags[0].Value]' --output text\n\naws ec2 terminate-instances --profile $PROFILE --region $REGION --instance-ids $INSTANCEID\n```\n\n\n## Initial configuration \n\nGet all the necessary AWS stuff setup, permissions, etc:\n\n```\n# http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html\ncat \u003c\u003c EOF \u003e ec2-role-trust-policy.json\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Principal\": { \"Service\": \"ec2.amazonaws.com\"},\n      \"Action\": \"sts:AssumeRole\"\n    }\n  ]\n}\nEOF\n\naws iam create-role \\\n    --profile $PROFILE \\\n    --region $REGION \\\n    --role-name s3-put-role \\\n    --description \"Write access to S3 $BUCKET\" \\\n    --assume-role-policy-document file://ec2-role-trust-policy.json\n\n# https://aws.amazon.com/blogs/security/a-safer-way-to-distribute-aws-credentials-to-ec2/\n# http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_s3_deny-except-bucket.html\n# http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_s3_rw-bucket-console.html\ncat \u003c\u003c EOF \u003e s3-put-policy.json\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"s3:PutObject\"\n      ],\n      \"Resource\": [\n        \"arn:aws:s3:::$BUCKET/*\"\n      ]\n    }\n  ]\n}\nEOF\n\naws iam put-role-policy \\\n    --profile $PROFILE \\\n    --region $REGION \\\n    --role-name s3-put-role \\\n    --policy-name s3-put-policy \\\n    --policy-document file://s3-put-policy.json\n\naws iam create-instance-profile --profile $PROFILE --region $REGION --instance-profile-name s3-put-profile\n\naws iam add-role-to-instance-profile --profile $PROFILE --region $REGION --instance-profile-name s3-put-profile --role-name s3-put-role\n\n\n# http://docs.aws.amazon.com/cli/latest/reference/s3api/create-bucket.html\naws s3api list-buckets --profile $PROFILE --region $REGION\naws s3api create-bucket --profile $PROFILE --region $REGION --bucket $BUCKET --acl private\n\n# http://docs.aws.amazon.com/cli/latest/userguide/cli-ec2-keypairs.html\n# http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html#how-to-generate-your-own-key-and-import-it-to-aws\nKEYPAIR=ec2-keypair\nREGION=us-east-1\naws ec2 delete-key-pair --key-name $KEYPAIR --region $REGION\naws ec2 import-key-pair --key-name $KEYPAIR --public-key-material fileb://~/.ssh/id_rsa.pub --region $REGION\naws ec2 describe-key-pairs --profile $PROFILE --region $REGION\n#aws ec2 create-key-pair --profile $PROFILE --key-name $KEYPAIR --query 'KeyMaterial' --output text \u003e ~/.ssh/$KEYPAIR.pem\n#chmod 400 ~/.ssh/$KEYPAIR.pem\n\n# http://skillslane.com/aws-tutorial-vpc-launch-instance-cli/\n# http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/vpc-subnets-commands-example.html\n# https://console.aws.amazon.com/vpc/home?region=$REGION\nVPCID=`aws ec2 describe-vpcs --profile $PROFILE --region $REGION --query 'Vpcs[*].VpcId' --output text`\necho $VPCID\n\n# http://docs.aws.amazon.com/cli/latest/userguide/cli-ec2-sg.html\n# http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-network-security.html\n# http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_SecurityGroups.html#VPC_Security_Group_Differences\naws ec2 describe-security-groups --profile $PROFILE --region $REGION\nSGID=$(aws ec2 create-security-group \\\n    --profile $PROFILE \\\n    --region $REGION \\\n    --vpc-id $VPCID \\\n    --group-name ssh-anywhere \\\n    --description \"SSH from anywhere\"\n    --query 'GroupId'\n    --output text)\naws ec2 authorize-security-group-ingress --profile $PROFILE --region $REGION --group-id $SGID --protocol tcp --port 22 --cidr 0.0.0.0/0\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frogusdev%2Fcountbits","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frogusdev%2Fcountbits","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frogusdev%2Fcountbits/lists"}